微机(第四版)戴梅萼_第三章_习题答案
3.12 用乘法指令时,特别要注意先判断用有符号数乘法指令还是用无符号数乘法指令,这是为什么?
[ 解答 ] 用乘法指令时,特别要注意先判断用有符号数乘法指令还是用无符号数乘法指令,是因为在执行乘法运算时,要想使无符号数相乘得到正确的结果,有符号数相乘时,就得不到正确的结果;要想使有符号数相乘得到正确的结果,无符号数相乘时,就得不到正确的结果。
3.13 字节扩展指令和字扩展指令用在什么场合?举例说明。
[ 解答 ] 遇到两个字节相除时,要预先执行 CBW 指令,以便产生一个双倍长度的被除数。否则就不能正确的执行除法操作。 CWD 同理。
3.14 什么叫 BCD 码?什么叫组合的 BCD 码?什么叫非组合的 BCD 码? 8086 汇编语言在对 BCD 码进行加、减、乘、除运算时,采用什么方法?
[ 解答 ] 在计算机中,可用 4 位二进制码表示一个十进制码,这种代码叫 BCD 码;用一个字节表示 2 位 BCD 码就是 BCD 码;计算机对 BCD 码进行加、减、乘、除运算,通常采用两种办法:一种是在指令系统中设置一套转专用于 BCD 码的指令;另一种方法是利用对普通二进制数的运算指令算出结果,然后用专门的指令对结果进行调整,或者反过来,先对数据进行调整,再用二进制数指令进行运算。(以上 7 题由陈军解答)
3.15 用普通运算指令执行 BCD 码运算时,为什么要进行十进制调整?具体讲 , 在进行 BCD 码的加、减、乘、除运算时,程序段的什么位置必须加上十进制调整指令?
[ 解答 ] 在 BCD 码中,只允许 0?/FONT>9 这 10 个数字出现,但有时候的运算结果会超过此范围,因此要进行十进制调整。进行加、件或乘法运算时,调整指令必须紧跟在算术指令后面,在进行除法运算时,调整指令放在除法指令之前。
3.18 用串操作指令设计实现以下功能的程序段:首先将 100H 个数从 2170H 处搬到 1000H 处,然后,从中检索相等于 AL 中字符的单元,并将此单元值换成空格符。
[ 解答 ] BUFF1 EQU , 1000H
BUFF2 EQU , 2170H
START : MOV SI , OFFSET BUFF2
LEA DI , BUFF1
MOV CX , 100H
CYCLE : MOV AL , [SI]
MOV [DI] , AL
INC SI
INC DI
LOOP CYCLE
ANOTHER : MOV DI , OFFSET BUFF1
MOV CX , 100
CLD
AGE : SCASB
DEC CX
JZ FIN
JNZ AGE
JMP OVER
FIN : MOV [DI] , 20H
CMP CX , 0
JNZ AGE
OVER : RET
3.20 带参数的返回指令用在什么场合?设栈顶地址为 3000H ,当执行 RET 0006 后, SP 的值为多少?
[ 解答 ] 带参数的返回指令可用在这样的情况:主程序为某个子程序提供一定的参数或者参数地址先送到堆栈中,通过堆栈传递给子程序。当栈顶指针 SP=3000H ,执行 RET 0006 时,弹出 3000H 和 3001H 处的返回地址,腾出 3002H?/FONT>3007H 的空间,所以 SP=3008H 。(以上 6 题由张丽解答)
.22 中断指令执行时,堆栈的内容有什么变化?中断处理子程序的人口地址是怎样得到的?
[ 答案 ] 中断指令执行时,堆栈内容变化如下:标志寄存器被推入堆栈,且 SP 减 2 ,然后 CPU 将主程序的下一条指令地址即断点地址的段值和偏移量推入堆栈,且 SP 减 4 。
某中断处理子程序的入口地址即中断向量,由该中断类型号的 4 倍为内存地址,在该地址处的 4 个字节内容即该中断向量。
3.23 中断返回指令 IRET 和普通子程序返回指令 RET 在执行时,具体操作内容什么不同?
[ 答案 ] IRET 须弹出堆栈中标志寄存器的值,而 RET 则不需要。
3.29 下面的程序段将 ASCII 码的空格字符填满 100 个字节的字符表。阅读这一程序,画出流程,并说明使用 CLD 指令和 REP STOSB 指令的作用,再指出 REP STOSB 指令执行时和那几个寄存器的设置有关?
MOV CX, SEG TABLE ; TABLE 为字节表表头
MOV ES, CX
MOV DI, OFFSET TABLE ; DI 指向字节表
MOV AL, ' '
MOV CX, 64H ; 字节数
CALL FILLM ; 调用数子程序
...
...
FILLM: JCXZ EXIT ; CX 为 0 则退出
PUSH DI ; 保存寄存器
PUSH CX
CLD
REP STOSB ; 方向标志清零
POP CX ; 重复填数
POP DI
EXIT: RET
[ 答案 ] CLD 指令作用:方向标志清 0 ; REP STOSB 指令作用:重复 CX 次将 AL 中的字节填入 [ES:DI] 为起始的表内, DI 增量、减量根据 DF 确定: DF=0 , DI 每次增量; DF=1 , DI 每次减量。 STOSB 指令执时,与 AX 、 ES 、 DI 寄存器和 Flag 的 DF 位设置有关。流程图如右:
3.30 下程序将一个存储块的内容复制到另一个存储快,进入存储段时, SI 中为源区起始地址的偏移量, DI 中为目的区起始地址的偏移量, CX 中为复制的字节数。阅读程序并说明具体的 REP MOCSB 指令使用与那些寄存器有关?
PUSH DI ; 保存寄存器
PUSH SI
PUSH CX
CMP DI, SI ; 看源区和目的区的地址哪个高
JBE LOWER ; 如目的区地址底,则转移
STD ; 如目的区地址高,则设方向标志为 1
ADD SI, CX ; 从最后一个字节开始复制
DEC SI ; 调整源区地址
ADD DI, CX
DEC DI ; 调整目的区地址
JMP MOVEM
LOWER: CLD ; 从第一个字节开始复制
MOVEM: REP MOVSB
POP CX
POP SI
POP DI
RET
[ 答案 ] REP MOVSB 的作用是重复 CX 次将 [DS:SI] 中字节传送到 [ES:DI] 中。 SI 、 DI 加或减 1 由 DF 确定, DF=0 ,加。 REP 使 CX 减 1 ,到 0 后结束传送。所以 REP MOVSB 指令与 CX 、 SI 、 DI 、 ES 、 DS 寄存器和 Flag 的 DF 位设置有关。
3.32 下面的程序实现在 TABLE 为起始地址的 100 个字符长度的表中检索 “$" 字符。分析程序,然后说明 REPNE SCASB 指令的具体执行过程。
START: MOV CX, SEG TABLE ; 表段地址送 ES
MOV ES, CX
MOV DI, OFFSET TABLE ; 表偏移量送 DI
MOV AL, '$' ; 检索的关键字
MOV CX, 64H ; 检索的字节数
PUSH DI ; 保存起始地址
CLD ; 清除方向标志
REPNE SCASB ; 检索
JNZ NFOUN ; 如未找到,则转移
SUB DI, 1 ; 找到,则指向次字符
JMP EXIT
NFOUN: POP DI ; 恢复起始地址
EXIT: RET ;( 以上由 1007 孙成长输入 )
[ 答案 ]REPNE SCASB 指令的作用将 AL 中的字节与 [ES:DI] 中的字节比较,不相等则 DI 加或减 1 后继续比较。这样可以在 [ES:DI] 起始的内存中检索到字节 AL ,一旦找到则操作结束,一直未找到则重复 CX 次。 ( 以上 6 题由张娅琴解答
3.35 下面的一个实现 16 位非组合 BCD 码相加的程序段,阅读这一程序段后再设计一个实现 16 位非组合 BCD 码减法的程序。
ANBCD: MOV CH, AH ; 进入程序段时, AX 中为第二个操作数
ADD AL, BL ; BX 中为被加数,实现低 8 位相乘
AAA
XCHG AL, CH
ADC AL, BH ; 实现高 8 位相加
AAA
MOV AH, AL ; 和保存在 AX 中
MOV AL, CH
RET
[ 答案 ] SUBCD: MOV CH, AH ; AX-BX->AX ,为非组合 BCD 码
SUB AL, BL
AAS
XCHG AL,CH
SBB AL,BH
AAS
MOV AH,AL
MOV AL,CH
RET
3.38 以下程序将一个 8 位二进转换为 2 位 BCD 数字,进入程序时, AL 中为二进制数,退出程序时,如 CF 为 0 ,则 AL 中为 BCD 数字,如 CF 为 1 ,则表示由于输入值超出范围故结果无效。阅读下面程序后,画出流程图,然后设计一个将组合的 BCD 码 (2 位 ) 转换为 8 位二进制数的程序。 [ 答案 ] 流程图如右:
START: CMP AL, 99 ; 是否超出范围?
JBE STRAT
STC ; 是,则转 EXIT ,并给 CF 置 1
JC EXIT
STRAT: MOV CL, 10 ; 10 作为除数
XOR AH, AH
CBW ; 将 AL 中数扩展到 AH
DIV CL ; 除法结果 AL 中为高位, AH 中为低位
MOV CL, 4
SHL AL, CL ; 左移 4 位
OR AL, AH ; 合成 BCD 码在 AL 中
EXIT: RET ; (以上 6 题由张琼仙解答)
第3章 8086指令系统及寻址方式
1. 根据下列要求编写一个汇编语言程序::
(1) 代码段的段名为COD_SG
(2) 数据段的段名为DAT_SG
(3) 堆栈段的段名为STK_SG
(4) 变量HIGH_DAT 所包含的数据为95
(5) 将变量HIGH_DAT 装入寄存器AH ,BH 和DL
(6) 程序运行的入口地址为START
答案:
DAT_SG SEGEMNT
HIGH_DAT DB 95
DAT_SG ENDS
;
STK_SG SEGMENT
DW 64 DUP(?)
STK_SG ENDS
;
COD_SG SEGMENT
MAIN PROC FAR
ASSUME CS: COD_SG, DS: DAT_SG, SS: STK_SG
START: MOV AX, DAT-SG
MOV DS, AX
MOV AH, HIGH_DAT
MOV BH, AH
MOV DL, AH
MOV AH, 4CH
INT 21H
MAIN ENDP
COD_SG ENDS
END START
2. 指出下列程序中的错误:
STAKSG SEGMENT
DB 100 DUP(?)
STA_SG ENDS
DTSEG SEGMENT
DATA1 DB ?
DTSEG END
CDSEG SEGMENT
MAIN PROC FAR
START: MOV DS,DA TSEG
MOV AL,34H
ADD AL,4FH
MOV DATA,AL
START ENDP
CDSEG ENDS
END
答案:
改正后:
STAKSG SEGMENT
DB 100 DUP(?) ENDS
DTSEG SEGMENT
DATA1 DB ?
DTSEG CDSEG SEGMENT
MAIN PROC FAR
START: MOV AL, 34H
ADD AL, 4FH
MOV DATA1, AL
ENDP
CDSEG ENDS
END 3. 将下列文件类型填入空格:
(1) .obj (2) .exe (3) .crf (4) .asm (5) .lst (6) .map
编辑程序输出的文件有______________________________________;
汇编程序输出的文件有______________________________________;
连接程序输出的文件有______________________________________。
答案:编辑程序输出文件: (4)
汇编程序输出文件: (1), (3), (5)
连接程序输出文件: (2), (6)
4. 下列标号为什么是非法的?
(1) GET.DATA (2) 1_NUM (3) TEST-DATA (4) RET (5) NEW ITEM
答案:非法标号: (1)因为‘. ’只允许是标号的第一个字符
(2)第一个字符不能为数字
(3)不允许出现‘-’
(4)不能是保留字, 如助记符
(5)不能有空格
5. 下面的数据项定义了多少个字节?
DATA_1 DB 6 DUP(4 DUP(0FFH))
答案:24字节
6. 对于下面两个数据段,偏移地址为10H 和11H 的两个字节中的数据是一样的吗?为什么? DTSEG SEGMENT | DTSEG SEGMENT
ORG 10H | ORG 10H
DATA1 DB 72H | DATA1 DW 7204H
DB 04H | DTSEG ENDS
DTSEG ENDS |
答案:不一样. 分别是72H, 04H和04H, 72H. 存储字时低8位存在低字节, 高8位存在高字节.
7. 下面的数据项设置了多少个字节?
(1) ASC_DATA DB ‘1234’ (2) HEX_DATA DB 1234H
答案 (1) 设置了4个字节 (2) 设置了2个字节
8. 执行下列指令后, AX寄存器中的内容是什么?
TABLE DW 10,20,30,40,50
ENTRY DW 3
MOV BX,OFFSET TABLE
ADD BX,ENTRY
MOV AX,[BX]
答案: (AX)=40
9. 指出下列指令的错误:
(1) MOV AH,BX (2) MOV [SI],[BX] (3) MOV AX,[SI][DI]
(4) MOV AX,[BX][BP] (5) MOV [BX],ES:AX (6) MOV BYTE PTR[BX],1000
(7) MOV AX,OFFSET [SI] (8) MOV CS,AX (9) MOV DS,BP
答案:(1) 源、目的字长不一致
(2) 源、目的不能同时为存贮器寻址方式
(3) 基址变址方式不能有 SI 和DI 的组合
(4) 基址变址方式不能有 BX 和BP 的组合
(5) 在8086寻址方式中,AX 不能作为基址寄存器使用, 而且源、目的不能同时为存贮器寻址方式
(6) 1000超出一个字节的表数范围
(7) OFFSET只用于简单变量,应去掉
(8) CS不能作为目的寄存器
(9) 段地址不能直接送入数据段寄存器
10. DA TA S EGMENT
TABLE_ADDR DW 1234H
DATA ENDS
MOV BX, TABLE_ADDR
LEA BX, TABLE_ADDR
请写出上述两条指令执行后, BX寄存器中的内容。
答案:MOV B X,TABLE_ADDR ; 执行后(BX)=1234H
LEA BX,TABLE_ADDR ; 执行后(BX)=OFFSET TABLE_ADDR
11. 设(DS)=1B00H, (ES)=2B00H, 有关存储器地址及其内容如右图
1B00:2000H 所示, 请用两条指令把X 装入AX 寄存器。
1B00:2002H 2B00:8000H
答案:LES BX, [2000H]
MOV AX, ES: [BX]
12. 变量DA TAX 和DATAY 定义如下:
DA TAX DW 0148H
DW 2316H
DA TAY DW 0237H
DW 4052H
按下述要求写出指令序列:
(1) DATAX 和DATAY 中的两个字数据相加, 和存放在DA TAY 和DATAY+2中。
(2) DATAX 和DATAY 中的两个双字数据相加, 和存放在DA TAY 开始的字单元中。
(3) DATAX 和DATAY 两个字数据相乘(用MUL )。
(4) DATAX 和DATAY 两个双字数据相乘(用MUL )。
(5) DATAX 除以23(用DIV )。
(6) DATAX 双字除以字DATAY (用DIV )。
答案:(1) MOV AX, DATAX
ADD AX, DATAY
MOV BX, DATAX+2
ADD BX, DATAY+2
MOV DATAY , AX
MOV DATAY+2, BX
(2) MOV AX, DATAX
ADD DATAY, AX
MOV AX, DATAX+2
ADC DATAY+2, AX
(3) MOV AX, DATAX
MUL DATAY
MOV DATAY ,AX
MOV DATAY+2,DX
(4)
MOV AX,WORD PTR DATAX
MOV BX,WORD PTR DATAY
MUL BX
MOV RESULT,AX
MOV RESULT+2,DX
MOV AX,WORD PTR DATAX
MOV AX,WORD PTR DATAY+2
MUL BX
ADD RESULT+2,AX
ADC RESULT+4,DX
MOV AX,WORD PTR DATAX+2
MOV BX,WORD PTR DATAY
MUL BX
ADD RESULT+2,AX
ADC RESULT+4,DX
MOV AX,WORD PTR DATAX+2
MOV BX,WORD PTR DATAY+2
MUL BX
ADD RESULT+4,AX
ADC RESULT+6,DX
(5) MOV AX, DATAX
MOV BL, 23
DIV BL
MOV BL,AH
MOV AH, 0
MOV DATAY , AX ; 存放商
MOV AL,BL
MOV DATAY+2, AX ; 存放余数
(6) MOV AX, DATAX
MOV DX, DATAX+2
DIV DATAY
MOV DATAY , AX
MOV DATAY+2, DX
13. 试分析下面的程序段完成什么操作?
MOV CL,04
SHL DX,CL
MOV BL,AH
SHL AX,CL
SHR BL,CL
OR DL,BL
答案:
将DX: AX中的双字左移4位(乘16)
14. 用其他指令完成和下列指令一样的功能:
(1) REP MOVSB (2) REP LODSB
答案:
(1) LOOP1:
MOV AL,BYTE PTR [SI]
MOV ES:BYTE PTR [DI], AL
INC SI 或: DEC SI
INC DI 或: DEC DI
LOOP LOOP1
(2) LOOP1:
MOV AL, BYTE PTR [SI]
INC SI 或: DEC SI
LOOP LOOP1
(3) LOOP1:
MOV ES:BYTE PTR [DI], AL
INC DI 或: DEC DI
LOOP LOOP1
(4) LOOP1: (3) REP STOSB (4) REP SCASB
CMP AL,ES:BYTE PTR [DI]
JE EXIT
INC DI 或: DEC DI
LOOP LOOP1
EXIT:
15. 编写程序段, 比较两个5字节的字符串OLDS 和NEWS, 如果OLDS 字符串与NEWS 不同, 则执行NEW_LESS, 否则顺序执行程序。
答案:LEA SI, OLDS
LEA DI, NEWS
MOV CX, 5
CLD
REPZ CMPSB
JNZ NEW_LESS
16. 假定AX 和BX 中的内容为带符号数, CX 和DX 中的内容为无符号数, 请用比较指令和条件转移指令实现以下判断:
(1) 若DX 的值超过CX 的值, 则转去执行EXCEED
(2) 若BX 的值大于AX 的值, 则转去执行EXCEED
(3) CX 中的值为0吗? 若是则转去执行ZERO
(4) BX 的值与AX 的值相减, 会产生溢出吗? 若溢出则转OVERFLOW
(5) 若BX 的值小于AX 的值, 则转去执行EQ_SMA
(6) 若DX 的值低于CX 的值, 则转去执行EQ_SMA
答案:(1) CMP DX, CX
JA EXCEED
(2) CMP BX, AX
JG EXCEED
(3) CMP CX, 0
JE ZERO
(4) SUB BX, AX
JO OVERFLOW
(5) CMP BX, AX
JL EQ_SMA
(6) CMP DX, CX
JB EQ_SMA
17. 假如在程序的括号中分别填入指令:
(1) LOOP L20 (2) LOOPNE L20 (3) LOOPE L20
试说明在三种情况下, 当程序执行完后, AX、BX 、CX 、DX 四个寄存器的内容分别是什么? TITLE EXLOOP.COM
CODESG SEGMENT
ASSUME CS:CODESG, DS:CODESG. SS:CODESG
ORG 100H
BEGIN: MOV AX,01
MOV BX,02
MOV DX,03
MOV CX,04
L20: INC AX
ADD BX,AX
SHR DX,1
( )
RET
CODESG ENDS
END BEGIN
答案:
(1)(AX )= 5 (BX )= 16 (CX )= 0 (DX )= 0
(2)(AX )= 2 (BX )= 4 (CX )= 3 (DX )= 1
(3)(AX )= 3 (BX )= 7 (CX )= 2 (DX )= 0
18. 变量N1和N2均为2字节的非压缩BCD 数码,请写出计算N1与N2之差的指令序列。
答案:
MOV AX, 0
MOV AL, N1+1
SUB AL, N2+1
AAS
MOV DL, AL
MOV AL, N1
SBB AL, N2
AAS
MOV DH, AL
19. 有两个3位的ASCII 数串ASC1和ASC2定义如下:
ASC1 DB ‘578’
ASC2 DB ‘694’
ASC3 DB ‘0000’
请编写程序计算ASC3←ASC1+ASC2。
答案:
CLC
MOV CX, 3
MOV BX, 2
BACK:
MOV AL, ASC1[BX]
ADC AL, ASC2[BX]
AAA
OR ASC3[BX+1], AL
DEC BX
LOOP BACK
RCL CX, 1
OR ASC3[BX], CL
20. 假设(CS)=3000H, (DS)=4000H, (ES)=2000H, (SS)=5000H, (AX)=2060H, (BX)=3000H, (CX)=5, (DX)=0, (SI)=2060H, (DI)=3000H, (43000H)=0A006H, (23000H)=0B116H, (33000H)=0F802H, (25060)=00B0H,.(SP)=0FFFEH, (CF)=1, (DF)=1, 请写出下列各条指令单独执行完后, 有关寄存器及存储单元的内容, 若影响条件码请给出条件码SF 、ZF 、OF 、CF 的值。
(1) SBB AX,BX (2) CMP AX,WORD PTR[SI+0FA0H]
(3) MUL BYTE PTR[BX] (4) AAM
(5) DIV BH (6) SAR AX,CL
(7) XOR AX,0FFE7H (8) REP STOSB
(9) JMP WORD PYR[BX] (10) XCHG AX,ES:[BX+SI]
答案:
(1) (AX)=0F05FH, (SF)=1, (ZF)=0, (OF)=0, (CF)=1
(2) (SF)=1, (ZF)=0, (OF)=1, (CF)=1
(3) (AX)=0240H, (OF)=1, (CF)=1
(4) (AX)=0906H, (SF)=0, (ZF)=0
(5) (AX)=20ACH
(6) (AX)=0103H, (CF)=0
(7) (AX)=0DF87H, (CF)=0, (OF)=0, (SF)=1, (ZF)=0
(8) (23000H)~(23004H)=60H, 不影响标志位
(9) (IP)=0A006H, 不影响标志位
(10) (AX)=00B0H, (25060)=2060H, 不影响标志位