《汇编语言》习题参考答案
1. 课程简介
本课程基于《汇编语言(第 2 版)》郑晓薇 编著,机械工业出版社,可以配合该教材使用。本课程由郑晓薇授权制作,提取教材中的实例以及实验内容,可以在实验楼环境中完成所有实例及实验。实验课程制作符合教材原版实例驱动教学以及实验训练贯穿始终的特点。
本教材可在 当当网 购买(点击链接即可进入购买页面)。
本课程实验列表中的最后模块(本节)为配套教材的习题参考答案,可供读者学习参考。
2. 习题参考答案
汇编语言是一门理论与实践相结合的课程,只有在大量的习题练习和编程训练下,才能很好地掌握基础理论与编程技巧。
本书在编写时采用实例与图示结合的方法使读者能够清楚、直观地看到程序的运行过程,便于更好地理解和掌握汇编语言。在每章内容之后都有相应的实验部分,旨在全面提升读者的综合应用能力和动手操作能力。每章之后的习题强调学习过程中的复习与练习,以加强读者对相关概念的学习与吸收。
本节给出教材各主要章节大部分习题的参考答案,供读者学习使用。
习题一答案
- 1.1
无符号数: 11010011=211=D3H,01110111=119=77H,10000011=131=83H,00101111=47=2FH,10101010=170=AAH
带符号数:11010011= -45=D3H,01110111=+119=77H,10000011= -125=83H,00101111=+47=2FH,10101010= -86=AAH
- 1.2
5E8AH,0BE6H,3DEH,4940H
- 1.3
00011101+00110101=01010010=52H=82, 01001001+11101000=00110001=31H=49, 10111110+01010010=00010000=10H=16, 10011010+11110001=10001011=8BH= -117
- 1.4
00101001+01010011=01111100+00000110=10000010=82H=82, 01110011-00100100=01001111-00000110=01001001=49H=49, 01100110+00011000=01111110+00000110=10000100=84H=84, 0000000100110010+01110101=0000000110100111+00000110 =0000001000000111=0207H=207
- 1.5
000020A3H,FF94H,00003456H,007FH,FFFFEC00H
- 1.6
无符号数:0~65535,0000H~FFFFH;带符号数:-32768~+32767,8000H~7FFFH
- 1.7
(1) 38H 等于十进制数 56,是十进制数 56 的补码,数字 8 的 ASCII 码,十进制数 38 的压缩 BCD 码
(2) FFH 等于十进制数 -1,是带符号数 -1 的补码,无符号数为 255
(3) 5AH 等于十进制数 90,是十进制数 90 的补码,大写字母 Z 的 ASCII 码
(4) 0DH 等于十进制数 13,是十进制数 13 的补码,回车符的 ASCII 码
- 1.8
(1) 108=01101100B=6CH,补码 01101100B,压缩 BCD 码 0000000100001000,ASCII 码 313038H
(2) 46=00101110B=2EH,补码 00101110B,压缩 BCD 码 01000110,ASCII 码 3436H
(3) –15=11110001B=F1H,补码 11110001B,ASCII 码 2D3135H
(4) 254=0000000011111110B=00FEH,补码 0000000011111110B,压缩 BCD 码 0000001001010100,ASCII 码 323534H
- 1.9
(1) 56+63=01110111B,CF=0,SF=0,ZF=0,OF=0 (2) 83-45=00100110B,CF=0,SF=0,ZF=0,OF=0 (3) -74+29=11010011B,CF=0,SF=1,ZF=0,OF=0 (4) -92-37=01111111B,CF=1,SF=0,ZF=0,OF=1
- 1.10
回车、换行、响铃、ESC 键、空格键、@、P、p
习题二答案
- 2.9
最少划分为 16 个逻辑段,最多划分为 65536 个逻辑段(每段 16 个字节)
- 2.10
CS:IP,DS:BX、SI、DI,ES:BX、SI、DI,SS:SP、BP
- 2.11
字节单元保存 8 位数,字单元保存 16 位数。根据源操作数的属性确定要访问的是字节单元还是字单元。
- 2.12
对于字节单元来说,偶地址和奇地址一样;对于字单元而言,最好用偶地址保存,可减少 CPU 的访存次数。
- 2.13
首单元的物理地址=38AE8H,末单元的物理地址=38AE8H+7FFFH=40AE7H
- 2.16
(1)物理地址=27679H
(2) 物理地址=20F92H
(3) 物理地址=20F92H
(2)和(3)的物理地址是一样的。说明逻辑地址不唯一,多个逻辑地址可对应到同一个物理单元上。
- 2.17
代码段 CS:IP 的物理地址=55A84H,堆栈段 SS:SP 的物理地址=4DB65H,数据段 DS:BX 的物理地址=17678H,附加段 ES:DI 的物理地址=2BA41H
- 2.18
当前栈指针所指单元的物理地址是 1522CH。堆栈区中还能保存 254 个字。
- 2.19
执行 E 200
- 2.20
执行 U 100
- 2.21
执行 R CX,然后输入 100
- 2.22
执行 E DS:0 ‘a’ ‘b’ ‘c’ ‘d’
习题三答案
- 3.3
MOV AX,BX ;源操作数为寄存器寻址,EA 无,物理地址 无 MOV AX,1290H ;立即寻址,EA 无,物理地址 无 MOV AX,[BX] ;寄存器间接寻址,EA=1290H, 物理地址=2FBB0H MOV AX,DS:[1290H] ;直接寻址,EA=1290H, 物理地址=2FBB0H MOV AX,[BP] ;寄存器间接寻址,EA=6756H, 物理地址=26A56H MOV [DI][BX],AX ;目的操作数为基址变址寻址,EA=3C06H, 物理地址=32526H MOV ES:[SI],AX ;寄存器间接寻址,EA=348AH, 物理地址=50CAAH
- 3.7
MOV AX,[CX] ;错。CX不能为间址寄存器 MOV AL,1200H ;错。立即数超出8位寄存器范围 MOV AL,BX ;错。两个操作数不匹配 MOV [SI][DI],AX ;错。两个变址寄存器不能在一起 MOV ES:[DX],CX ;错。DX不能为间址寄存器 MOV [AX],VALUE ;错。AX不能为间址寄存器 MOV COUNT,[SI] ;错。两个操作数不能都是存储单元
- 3.8
;(1) MOV AX,BX ;(2) MOV CL,15 ;(3) ADD AX,[BX] ;(4) MOV [BX+SI],AL ;(5) MOV AX,VALUE[SI] ;(6) SUB AX,DS:[2000H]
- 3.9
;(1) ADD AX,[X+3] ;(2) MOV BX,3 ;(3) MOV BX,3 MOV Y,AX ADD AX,X[BX] MOV SI,OFFSET X MOV Y,AX ADD AX,[BX+SI] MOV Y,AX
- 3.10
立即寻址方式中操作数(立即数)和指令一起存放在代码段中。
习题四答案
- 4.10
;(1) DATA SEGMENT X DW 0 Y DW 0 DATA ENDS ;(2) STRING DB ’Computer’ ;(3) COUNT DB 100 DUP(?) ;(4) PI EQU 3.14 ;(5) VALUE LABEL BYTE
- 4.11
(1)对。
(2)错。260 超出了字节范围。
(3)错。X3 是字节型,1234H 是字型,不匹配。
(4)对。
(5)错。缺少 DUP。
(6)对。
- 4.12
(1)AL=3。
(2)AX=2103H。
(3)DX=TABLE 的偏移地址。
(4)CL=33H
(5)BX=TABLE 的段地址。
(6)BX=1。
(7)DX=TABLE 的偏移地址。
- 4.13
MOV DX,2012H MOV AX,5D68H MOV CX,1003H MOV BX,49A6H ADD AX,BX (SUB AX,BX) ADC DX,CX (SBB DX,CX)
- 4.14
SUB AX,CX SBB DX,0
- 4.15
MOV AX,extra MOV ES,AX
- 4.16
;(1) MOV AL,16 ADD AL,X MOV BL,5 IMUL BL MOV Z,AX ;(2) MOV BL,4 MOV AL,X IDIV BL SUB AL,Y MOV Z,AX ;(3) MOV AL,X MOV BL,8 IMUL BL MOV DX,AX MOV AH,0 MOV AL,Y MOV BL,16 IDIV BL CBW ADD DX,AX MOV AH,0 MOV AL,W IMUL AL SUB DX,AX MOV Z,DX ;(4) MOV AL,X ADD AL,Y MOV BL,X SUB BL,Y MOV AH,0 IMUL BL MOV Z,AX MOV AL,X IDIV Y CBW SUB Z,AX
- 4.17
Z = (5+22-15)*14= 168
- 4.18
从伪指令 END START 处获知程序从 START 标号开始。
- 4.19
(1)减法:
MOV AX,8576H MOV BX,9988H SUB AX,BX
结果:AX=EBEEH,CF=1,OF=0,ZF=0,SF=1
(2) 加法:
MOV AX,8576H MOV BX,9988H ADD AX,BX
结果:AX=1EFEH,CF=1,OF=1,ZF=0,SF=0
- 4.21
;(1) MOV AL,56H MOV BL,34H ADD AL,BL DAA MOV Y1,AL ;(2) MOV AX,128H MOV BX,35H SUB AX,BX DAS MOV Y2,AL ;(3) MOV AL,68H MOV BL,23H ADD AL,BL MOV BL,45H SUB AL,BL DAS MOV Y3,AL
- 4.22
;(1) MOV AX,0708H MOV BX,0406H ADD AL,BL ADD AH,BH ;不用带进位加 AAA ;加法调整,含进位调整 MOV BX,AX XCHG AH,AL ;高4位调整 AAA MOV BH,AL MOV Z1,BX ;保存十位、各位,百位在CF中 ;(2) MOV AX,0905H MOV BX,0207H SUB AL,BL SUB AH,BH ;不用带借位减 AAS ;减法调整 MOV Z2,AX ;(3) MOV AX,0102H MOV BX,0006H MUL BX ;乘法先不用调整 MOV BX,0303H SUB AX,BX AAS ;减法调整 MOV Z3,AX ;(4) MOV AX,0704H MOV BX,0108H ADD AL,BL ADD AH,BH AAA ;加法调整 MOV BL,6 AAD ;除法调整 DIV BL MOV BH,AH ;余数保存在BH AND AX,000FH AAA ;商调整 MOV Z4,AX ;保存商
- 4.23
编程序。从键盘输入一个数字,去掉 ASCII 码后保存到 BUFF 单元。
.model small .data buff db ? .code start: mov ax,@data mov ds,ax mov ah,1 ;键盘输入 int 21h sub al,30h ;去掉ASCII码 mov buff,al mov ah,4ch int 21h end start
- 4.24
编程序。将键盘输入的小写字母变为大写字母显示在屏幕上。
.model small .code start: mov ah,1 ;键盘输入 int 21h sub al,20h ;变为大写 mov dl,al mov ah,2 int 21h mov ah,4ch int 21h end start
- 4.25
X 和 Y 都是字节型数据,编写将两数相加的结果显示出来的程序段。
.model small .data x db 12h y db 34h .code start: mov ax,@data mov ds,ax mov al,x add al,y ;结果为46H mov ah,al ;AH=46H and al,0fh ;AL=06H mov cl,4 rol ah,cl ;AH=64H and ah,0fh ;AH=04H add ax,3030h ;AX=3436H mov bx,ax mov dl,bh ;显示4 mov ah,2 int 21h mov dl,bl ;显示6 int 21h mov ah,4ch int 21h end start
- 4.26
编写程序,建立一个 0~9 的平方根表,查表可得某数的平方根。
data segment x db '0.000','1.000','1.414','1.732','2.000' db '2.236','2.449','2.646','2.828','3.000' ;建立字符表 y db 5 dup(?) ;存放查到平方根 u db 3 ;要查的数 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov al,u ;要查的数 mov cl,5 mul cl ; (u×5=15号单元开始) mov ah,0 mov bx,ax ;地址保存到bx mov si,0 let1: mov al,x[bx] ;取出平方根数字 mov y[si],al ;存入y inc si inc bx loop let1 ;循环取出5次 mov ah,4ch int 21h code ends end start
- 4.27
编写查表程序。建立一个班级姓名表,给出学号,可显示出其姓名。
.model small .data x1 db 'zhang yan $' ;姓名为10个字符宽度 x2 db 'li li $' x3 db 'wang lan $' x4 db 'zhao xue $' x5 db 'li jiang $' u db 3 ;要查的学号 .code start: mov ax,@data mov ds,ax mov al,u ;给出学号 mov cl,10 mul cl ;u×10=30(号单元开始) mov ah,0 mov dx,ax ;地址保存到dx mov ah,9 ;9号功能显示字符串 int 21h mov ah,4ch int 21h end start
- 4.28
编程实现公式计算 Z=X/4+16Y。
.model small .data x db 4 y db 6 z db ? .code start: mov ax,@data mov ds,ax mov al,x ; mov cl,2 sar al,cl ; X/4 mov cl,4 mov bl,y sal bl,cl ;16Y add al,bl ;X/4+16Y mov z,al mov ah,4ch int 21h end start
- 4.29
编写程序段,将 AL 中的数乘以 6,与 CL 相减后再除以 3;把商保存到 Y 单元,余数保存到 Y + 1 单元。
.model small .data y db ?,? .code start: mov ax,@data mov ds,ax mov al,3 ;设al=3 mov cl,6 mul cl ;al×6 mov cl,4 ;设cl=4 sub al,cl ;相减 mov bl,3 idiv bl ; /3 mov y,al ;商 mov y+1,ah ;余数 mov ah,4ch int 21h end start
习题五答案
- 5.11
进位标志 CF=1
- 5.12
先把 AX 的值除以 8 等于 0246H,再把高 12 位屏蔽为 0,剩下 AL=06H 加上 30H 变为 ASCII 码显示出来。
- 5.13
判断 X>0,是,Z=X-Y;否则 Z=X 的绝对值
- 5.14
(1) 目的操作数是存储单元时,要用 PTR 伪操作指出单元的属性。
(2) DS 段寄存器使用非法
(3) 立即数使用非法。
(4) 目的操作数不允许是立即数
(5) 两个操作数不允许都是存储单元
(6) 移位次数超过 1 要用 CL 表示。
- 5.15
AND AL,11011111B
- 5.16
(1) AL=30H
(2) AL=B7H
(3) AL=C8H
(4) AL=38H
- 5.27
分支程序设计。完成如下公式的计算,请写出程序。
(X+3)/2 X>0 Y=0 X=0 X×4 X<0
程序:
DATA SEGMENT X DB 23 Y DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV AL,X CMP AL,0 JE SUB2 JG SUB1 MOV CL,2 SAL AL,CL JMP SHORT SUB2 SUB1: ADD AL,3 SAR AL,1 SUB2: MOV Y,AL MOV AH,4CH INT 21H CODE ENDS END START
- 5.28
设 X、Y、Z 为字节单元。如果 X≥0,Z=4X-Y/16,否则,Z=X 的绝对值。编程序实现。
程序如下:
DATA SEGMENT X DB 3 Y DB 5 Z DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX MOV AL,X CMP AL,0 JL SS1 MOV CL,2 SAL AL,CL MOV BL,Y MOV CL,4 SAR BL,CL SUB AL,BL JMP OUT1 SS1: NEG AL OUT1: MOV Z,AL MOV AH,4CH INT 21H CODE ENDS END START
- 5.29
字数组 M 中有 10 个数据,分类统计其中正数、负数、0 的个数,分别存入 POSI、NEGA、ZERO 单元。
程序如下:
DATA1 SEGMENT M DW 21,-34,32,112,-324,0,76,0,48,50 POSI DW ? NEGA DW ? ZERO DW ? DATA1 ENDS CODE1 SEGMENT ASSUME CS: CODE1,DS:DATA1 START: MOV AX,DATA1 MOV DS,AX MOV CX,10 LEA SI,M AGAIN: CMP WORD PTR [SI],0 JL LOWER JE EQUAL INC POSI JMP LPP1 LOWER: INC NEGA JMP LPP1 EQUAL: INC ZERO LPP1: ADD SI,2 DEC CX JNZ AGAIN MOV AH,4CH INT 21H CODE1 ENDS END START
- 5.30
试编写程序,从键盘接收一英文单词,以空格结束,将其存入 BUF 开始的存储单元中,并在最后加上字符串结束符 ’$’。
主要程序部分:
LEA BX,BUF LOP: MOV AH,1 INT 21H CMP AL,20H JE NEXT MOV [BX],AL INC BX JMP LOP NEXT: MOV BYTE PTR[BX],’$’
- 5.31
编程。将 AX 寄存器中的 16 位数分成 4 组,每组 4 位,从低到高分别放在 AL,BL,CL,DL 中。
程序段:
START:MOV AX,1234H MOV BX,AX AND AL,0FH ;4 AND BL,0F0H ;3 AND AH,0FH MOV CL,AH ;2 AND BH,0F0H MOV DL,BH ;1
习题六答案
- 6.11
累加和 TOTAL=83
- 6.12
循环统计 X 中 0 的个数
- 6.13(1) 将 BB1:RCL AL,1 改为 BB1:ROL AL,1
(2) 将
BB2:CMP [BX],’T’ LOOPNE BB2
改为:
DEC BX BB2:INC BX CMP [BX],’T’ LOOPNE BB2
- 6.15
计算 Y=1×2+3×4+5×6+7×8+9×10 的程序段。
MOV AL,1 MOV BL,2 MOV DX,0 MOV CX,5 AA1:MUL BL ADD DX,AX INC BL MOV AL,BL INC BL LOOP AA1
- 6.16
写程序段。查找 CATT 表中的字符”@”,找到后将 SIGN 单元置 1,否则 SIGN 单元置 0。
catt db 'asd@ddd' sign db ? …… mov ax,extra mov es,ax mov sign,0 mov al,'@' lea di,catt cld mov cx,7 repnz scasb jcxz nee mov sign,1 nee: mov ah,4ch int 21h
- 6.17
写程序段。在长度为 N 的字数组 VALUE 中统计负数的个数并保存到 AX 中。
value dw 2,-4,-5,3,6,6,-8 n equ ($-value)/2 ;元素个数 …… start: mov ax,data mov ds,ax mov cx,n mov bx,0 mov ax,0 rept1: mov si,value[bx] ;取出元素 cmp si,0 jge let1 ;≥0 转let1 inc ax ;为负数,ax加1 let1: add bx,2 loop rept1
- 6.18
从键盘输入一个数字,在屏幕上显示出以该数字开始 10 个数字串。
CODE SEGMENT ASSUME CS:CODE START: MOV AH,1 INT 21H MOV CX,10 MOV BL,AL REPT1: CMP BL,'9' JLE NEXT SUB BL,10 NEXT: MOV DL,BL MOV AH,2 INT 21H INC BL LOOP REPT1 MOV AH,4CH INT 21H CODE ENDS END START
- 6.19
编程。比较两个字符串是否相同,统计并显示出相同的字符个数和不同的字符个数。
data segment bunch1 db 'stadent' bunch2 db 'studEnt' data ends code segment assume cs:code,ds:data,es:data start: mov ax,data mov ds,ax mov es,ax lea si,bunch1 lea di,bunch2 mov bx,0 ;bh=相同的个数,bl=不同的个数 mov cx,7 let1: mov al,[si] cmp al,[di] ;两字符比较 jz equl ;相同转equl inc bl ;不同bl加1 jmp out1 equl: inc bh out1:inc si inc di loop let1 mov dl,'n' ;显示'n',代表不同 mov ah,2h int 21h add bl,30h ;加上ASCII码 mov dl,bl ;显示不同的个数 int 21h mov dl,'e' ;显示'e',代表相同 int 21h add bh,30h mov dl,bh ;显示相同的个数 int 21h mov ah,4ch int 21h code ends end start
- 6.21
STRI 单元存有 10 个字符的字符串,以 0 结尾,编程去掉其中的空格符,并将后续字符向前递补。
DATA SEGMENT STR DB ‘SDABF G H0’ DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX LEA DI,STR SPACE:MOV CX,10 MOV AL,[DI] CMP AL,0 JE OUT CMP AL,20H JE DELETE JMP EXIT SUB CX,DI MOV SI,DI DELETE: MOV BL,[SI+1] MOV [SI],BL INC SI LOOP DELETE EXIT:JMP SPACE OUT:MOV AH,4CH INT 21H CODE ENDS END START
- 6.23
将内存中用 ASCII 码表示的 100 以内的十进制数转变为二进制数。十进制数不够 3 位以 20H(空格)补齐。
设计思路:
(1)用 EQU 伪指令获得需转换的十进制数的个数;
(2)用双重循环。外循环控制个数,用 x 作为中间变量;
(3)内循环将一个 3 位十进制数去掉 ASCII 码后按位数扩大 10 倍再相加,保存后即存储为二进制数;
(4)分两个数组保存 ASCII 码表示的十进制数和转换后的二进制数。
程序如下:
; 6-23.asm 将内存中用ASCII码表示的100以内的十进制数转变为二进制数 data segment score1 db 36h,37h,20h,31h,30h,30h,38h,35h,20h,31h,30h,30h ;即67,100,85,100 x dw ? n equ 3 ;三位数 num equ (x-score1)/n ;十进制数个数 score2 dw num dup(0) ;保存转换后的二进制数 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov cx,num mov si,-2 mov bx,0 rept1: push cx ;保存外循环次数 mov cx,n rept2: mov al,score1[bx] ;从score1取数 cmp al,30h ;判断是否0-9 jl exit cmp al,39h jg exit and ax,000fh ;去掉ASCII码 xchg ax,x mov dx,10 ;将ax中前一次形成的数扩大10倍 mul dx xchg ax,x add x,ax ;相加后保存到x exit: inc bx ;取下一位数 loop rept2 pop cx ;弹出外循环次数 add si,2 mov ax,x mov score2[si],ax ;转换后的数据保存到score2 mov x,0 loop rept1 mov ah,4ch int 21h code ends end start
运行结果:

可以看到,67 转换为 0043,100 转换为 0064,85 转换为 0055。在 DEBUG 下显示的内存单元是十六进制表示,实际存储的是二进制数。
习题七答案
- 7.12
功能:两个字节数相加。X 和 BL 相加保存到 Y。
- 7.13
功能:键盘输入的字符保存到 KEY 单元中,直到按回车为止。
- 7.14
功能:将 X 单元中的十六进制 3AH 变为十进制入栈保存,AH 中为余数。先将 0008H 入栈,再将 0005H 入栈,结果为 58。
- 7.16
写出子程序,从键盘输入一个多位十进制数,并分别保存到 BUFFER 开始的单元中。
KEY_IN PROC PUSH AX PUSH BX MOV BX,0 LET1:MOV AH,1 INT 21H CMP AL,0DH ;输入回车退出 JZ EXIT MOV BUFFER[BX],AL ;保存到BUFFER INC BX JMP LET1 EXIT:POP BX POP AX RET KEY_IN ENDP
- 7.17
从键盘输入多位数字,转换成十进制数并保存到 X 单元中。
KEY_IN_DEC PROC PUSH AX PUSH BX MOV X,0 MOV BX,0 MOV SI,0 LET1:MOV AH,1 INT 21H CMP AL,0DH ;输入回车退出 JZ EXIT MOV BUFFER[SI],AL ;保存到BUFFER INC SI JMP LET1 EXIT:MOV CX,SI ;位数放在CX MOV SI,0 LET2:MOV AL, BUFFER[SI] SUB AL,30H MOV AH, 0 XCHG AX,X ;形成十进制数 MOV BX,10 MUL BX XCHG AX,X ADD X,AX ;保存 INC SI LOOP LET2 POP BX POP AX RET KEY_IN _DEC ENDP
- 7.23
写出对内存单元 X 中的补码求真值子程序,补码保存在 AX 中。
calcu proc push ax push bx push si mov ax,0 mov al,x and al,al jns zz neg al mov fuhao,'-' zz: mov si,0 mov bx,10 ;将ax变为十进制数真值 let1: mov dx,0 inc si ;统计余数个数 idiv bx mov y[si], dx ;在y单元保存余数 cmp ax,0 jnz let1 pop si pop bx pop ax ret calcu endp
- 7.30
编制一个计算数组中所有负数之和的子程序。并利用此子程序分别计算 A 数组和 B 数组中的负数之和,结果分别放在 SUM1 和 SUM2 单元中。
DATA SEGMENT A DB 9,-8,-7,6,5 B DB -8,7,6,-5,4 SUM1 DB ? SUM2 DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV CX,5 MOV SI,OFFSET A CALL LADD MOV SUM1,BL MOV SI,OFFSET B CALL LADD MOV SUM2,BL MOV AH,4CH INT 21H LADD PROC NEAR PUSH CX PUSH AX PUSH SI XOR BL,BL NEXT: MOV AL, [SI] AND AL,AL JNS JJJ ADD BL,AL JJJ: INC SI LOOP NEXT POP SI POP AX POP CX RET LADD ENDP CODE ENDS END START
习题八答案
- 8.16
宏的作用:DOS 功能调用。功能号用哑元指出。
- 8.17
宏的作用:两个操作数相加,结果保存在第 3 个数中。
- 8.18
宏的作用:DOS 的 2 号显示功能。
- 8.19
宏的作用:定义 VALUE 数组,数组长度和初值由哑元指出。
- 8.20
缺少标号定义 LOCAL LETT1。宏的作用:两个哑元相减,结果为负则求补。
- 8.27
程序:
.model small .stack 100h .code start: input ;键盘输入 add al,20h ; 大写变为小写 output al ; 显示 mov ah,4ch int 21h end start
- 8.28
程序:
.model small .data alpha db ‘Computer’ .code start: display alpha ;显示字串 mov ah,4ch int 21h end start
- 8.29
程序:
.model small .stack 100h .code start: input ;键盘输入 cmp al,‘-’ jnz start neg x ;求补 mov ah,4ch int 21h end start
- 8.30
程序:
.model small .stack 100h .code start: input ;键盘输入 mov bl,al input ;输入第2个数 add al,bl mov ah,0 aaa ;非压缩BCD码加法调整 add ax,3030h output ah ;显示高位 output al ;显示低位 mov ah,4ch int 21h end start
习题九答案
- 9.26
在屏幕的 row1、rank1 到 row2、rank2 开窗口,清窗口,设置字符颜色为 color。
- 9.27
将光标设置在 5 行 10 列上。
- 9.28
回车换行宏。
- 9.29
读取时钟计数器当前计数值,cx 保存高位,dx 保存低位;判断计数是否到 91 次(5 秒),没到,继续循环读取,到 5 秒后做下面内容。
- 9.30
设置 1CH 号中断的中断向量(win_time),将其保存到中断向量表中。
- 9.35
编程实现在窗口中将键盘输入的小写字母加密后显示出来。
程序如下:
include 9-3.mac ;参见教材9.3.1节示例9-3,9-3.mac宏库 .model small .data letter db 'Input Letter: $' cont db ? .code start: mov ax,@data mov ds,ax clearsc ;清屏 clearsw ;窗口清屏 reptt: ;置显示光标 mov ah,2 mov dh,11 ;在11行30列显示 mov dl,30 mov bh,0 int 10h ;显示串 mov ah,9 mov dx,offset letter int 21h ;置输入光标 mov ah,2 mov dh,15 ;在15行30列输入 mov dl,30 mov bh,0 int 10h ;输入小写字母 mov ah,1 int 21h add al,20h ;加密 ;显示加密后的字符 mov dl,al mov ah,2 int 21h ;开窗口 mov ah,6 mov al,1 ;上卷1行 mov ch,8 ;从8行30列到15行60列 mov cl,30 mov dh,15 mov dl,60 mov bh,27h ;绿底灰字 int 10h inc cont ;可输入3次 cmp cont,3 jne reptt out1: mov ah,4ch int 21h end start
- 9.36
编写程序,在屏幕上显示彩色的 26 个英文字母。
程序如下:
.model small .data letter db ? n='a' ;重复汇编 m=1eh ;蓝底黄字开始 rept 26 ;26个小写字母 db n,m n=n+1 m=m+1 endm .code start: mov ax,@data ;各个段都在代码段中 mov ds,ax ;开窗口 mov ah,06h mov al,0 mov bh,37h ;白底黑字0f0h,兰灰底灰白字37h,黄底白字0e7h mov ch,3 ;从8行30列到15行60列 mov cl,3 mov dh,15 mov dl,60 int 10h ;置光标 locate: mov ah,2 mov dh,6 ;光标在6行30列 mov dl,30 mov bh,0 int 10h ;显示彩色的26个英文字母 mov bx,offset letter+1 mov bp,bx mov bx,seg letter+1 mov es,bx mov ah,13h mov al,3 mov bh,0 mov cx,26 ;26个字母 int 10h mov ah,4ch int 21h end start
- 9.37
编写程序,在窗口中将键盘输入的一串字符中的大写字母和小写字母的个数分别统计并显示出来。
程序如下:
include 9-4.mac ;参见教材9.5.1节示例9-4,9-4.mac宏库 .model small .data mess1 db 'input: $' mess2 db 29,32 dup(?) daxie db ? xiaoxie db ? .code start: mov ax,@data mov ds,ax clearsc ;清屏 clearsw 8,30,15,60,27h ;开窗口,绿底灰白字 cursor 12,30 ;置显示光标 ;显示提示 mov ah,9 mov dx,offset mess1 int 21h ;输入串 mov al,0 mov ah,10 mov dx,offset mess2 int 21h ;统计 mov cx,0 mov cl,mess2+1 ;输入的个数 mov bx,2 ;从第2个单元存放键入的字母 let1: mov al,mess2[bx] test al,20h ;区分大小写 jz let2 ;为0,即大写转 inc xiaoxie ;小写加1 jmp let3 let2: inc daxie ;大写加1 let3: inc bx loop let1 windows 8,30,15,60,27h ;窗口内上卷 cursor 14,30 ;在16行30列显示 add xiaoxie,30h displ xiaoxie ;显示小写个数 windows 8,30,15,60,27h ;窗口内上卷 add daxie,30h displ daxie ;显示大写个数 out1: mov ah,4ch int 21h end start
- 9.38
编写对键盘输入一段英文的操作计时的程序。
程序如下:
include 9-4.mac .model small .data letter1 db 'Time start= ','$' letter2 db 'Time end = ','$' letter3 db 'Time total= ','$' input db 100,102 dup(?) hour db ? minutes db ? seconds db ? persec db ? cont db 0 .code start: mov ax,@data mov ds,ax clearsc ;清屏 cursor 2,50 ;置光标 mov ah,9 mov dx,offset letter1 ;显示串1 int 21h sss: ;读时间并显示 mov ah,2ch ;CH=小时,CL=分,DH=秒,DL=百分秒 int 21h mov bx,0 mov bl,ch call disp_2_10 ;显示小时 displ ':' ;显示: mov bx,0 mov bl,cl call disp_2_10 ;分 displ ':' ;显示: mov bx,0 mov bl,dh call disp_2_10 ;秒 displ ':' ;显示: mov bx,0 mov bl,dl call disp_2_10 ;百分秒 sub ch,hour ;计算时间差 sub cl,minutes sub dh,seconds sub dl,persec mov hour,ch ;保存时间差 mov minutes,cl mov seconds,dh mov persec,dl inc cont cmp cont,2 ;显示2次时间 jz out1 cursor 7,10 ;置输入光标 mov dx,offset input ;键盘输入 mov ah,10 int 21h cursor 3,50 ;置光标 ;显示串2 mov ah,9 mov dx,offset letter2 int 21h jmp sss out1: cursor 4,50 ;置光标 mov ah,9 mov dx,offset letter3 ;显示串3 int 21h ;显示时间差 mov cx,3 mov si,offset hour mov bx,0 www: mov bl,[si] ;取出时、分、秒 call disp_2_10 ;3次调用 displ ':' ;显示: inc si loop www mov ah,4ch int 21h ;子程序。二-十进制数转换。bx值用十进制显示。 disp_2_10 proc store_ss ;保护现场 mov ax,bx ;bx传参 mov cx,0 mov bx,10 ;将ax变为十进制数 let1: mov dx,0 inc cx ;统计余数个数 idiv bx push dx ;保存余数 cmp ax,0 jnz let1 let2: ;显示结果 pop ax ;将余数弹入ax add ax,0030h ;调整为ascii码 mov dl,al mov ah,2 int 21h loop let2 restore_ss ;恢复现场 ret disp_2_10 endp end start