计组与微机控制
第七章习题
第七章习题
第 1 题:判断源操作数和目的操作数的寻址方式
题目:试分别说明下列各指令中源操作数和目的操作数使用的寻址方式。
① AND AX, 0FFH ② CMP [SI], CX ③ MOV DS:[0FFFH], CL ④ SUB [BP][SI], AH ⑤ ADC AX, 0ABH[BX] ⑥ OR DX, -35[BX][DI] ⑦ PUSH DS ⑧ CMC ⑨ MOV EAX, [ECX][EBX] ⑩ MOV EAX, [ESI][EDX*2] ⑪ MOV EAX, EBX ⑫ MOV EAX, [ESI*2]
① AND AX, 0FFH
意思是:AX ← AX AND 00FFH
AX 是寄存器,0FFH 是直接给出的常数。
目的操作数 AX:寄存器寻址 源操作数 0FFH:立即寻址
② CMP [SI], CX
[SI] 表示用 SI 中的偏移地址去访问内存,即默认:DS:[SI]
目的操作数 [SI]:寄存器间接寻址 源操作数 CX:寄存器寻址
③ MOV DS:[0FFFH], CL
DS:[0FFFH] 直接给出了段寄存器和偏移地址。
目的操作数 DS:[0FFFH]:直接寻址 源操作数 CL:寄存器寻址
④ SUB [BP][SI], AH
[BP][SI] 等价于:[BP + SI]这是基址寄存器 BP 加变址寄存器 SI。
注意:只要用了 BP,默认段寄存器是 SS。
目的操作数 [BP+SI]:基址变址寻址 源操作数 AH:寄存器寻址
⑤ ADC AX, 0ABH[BX]
0ABH[BX] 等价于:[BX + 0ABH]也就是寄存器加位移量。
目的操作数 AX:寄存器寻址 源操作数 0ABH[BX]:寄存器相对寻址
⑥ OR DX, -35[BX][DI]
等价于:OR DX, [BX + DI - 35]
里面同时有:
BX:基址寄存器 DI:变址寄存器 -35:位移量
目的操作数 DX:寄存器寻址 源操作数 -35[BX][DI]:基址变址相对寻址
⑦ PUSH DS
DS 是段寄存器。PUSH DS 把 DS 的内容压入堆栈。
严格说:源操作数 DS:寄存器寻址,目的操作数:隐含为栈顶 SS:SP
所以可以写:源操作数 DS:寄存器寻址,目的操作数:隐含寻址,堆栈寻址
⑧ CMC
CMC 是进位标志取反:
CF ← 取反 CF
它没有显式操作数,操作对象隐含为标志寄存器中的 CF 位。
源操作数:隐含寻址,CF 目的操作数:隐含寻址,CF
或者简写:无显式操作数,隐含操作 CF 标志位
⑨ MOV EAX, [ECX][EBX]
等价于:MOV EAX, [ECX + EBX]
这是 32 位寻址方式。一个寄存器作基址,一个寄存器作变址,没有比例因子、没有位移量。
目的操作数 EAX:寄存器寻址 源操作数 [ECX+EBX]:基址变址寻址
⑩ MOV EAX, [ESI][EDX*2]
等价于:MOV EAX, [ESI + EDX*2]
这里有:
ESI:基址寄存器 EDX:变址寄存器 2:比例因子
这是 80386 以后增加的比例变址类寻址。
目的操作数 EAX:寄存器寻址 源操作数 [ESI+EDX*2]:基址加比例变址寻址
⑪ MOV EAX, EBX
MOV EAX, EBX
两个操作数都是 32 位通用寄存器。
目的操作数 EAX:寄存器寻址 源操作数 EBX:寄存器寻址
⑫ MOV EAX, [ESI*2]
MOV EAX, [ESI*2]
这是 32 位比例变址寻址,等价于:EA = ESI × 2
没有基址寄存器,也没有位移量,只有变址寄存器和比例因子。
目的操作数 EAX:寄存器寻址 源操作数 [ESI*2]:比例变址寻址
第 2 题:判断 8086/8088 指令语法是否有错
第 3 题:求标志位
题目:
MOV DL,86 ADD DL,0AAH
注意:86 没有 H,按十进制处理,所以:
86D = 56H 56H + AAH = 100H
结果:
DL = 00H CF = 1 AF = 1 ZF = 1 SF = 0 OF = 0
第 4 题:8086/8088 中可作地址指针的寄存器
8086/8088 中用于形成有效地址 EA 的主要寄存器是:
BX,BP,SI,DI
其中:
BX:基址寄存器,默认段 DS BP:基址寄存器,默认段 SS SI:源变址寄存器,默认段 DS DI:目的变址寄存器,默认段 DS
SP 虽然是堆栈指针,但不能像 BX、BP、SI、DI 那样直接写在一般内存寻址表达式中。
第 5 题:改写 MOV AX, OPRD
已知:
SS = 0915H DS = 0930H SI = 00A0H DI = 01C0H BX = 0080H BP = 0470H OPRD 的物理地址 = 095C0H
先算偏移地址。若用 DS:EA = 095C0H - 09300H = 02C0H
若用 SS:EA = 095C0H - 09150H = 0470H
所以可写成:
MOV AX, DS:[02C0H] ; 直接寻址 MOV AX, [BP] ; 寄存器间接寻址,默认 SS,BP=0470H MOV AX, 220H[SI] ; 寄存器相对寻址,SI+220H=02C0H MOV AX, 0C0H[BX][DI] ; 基址变址相对寻址,BX+DI+0C0H=02C0H
也可以写:
MOV AX, 100H[DI] ; DI+100H=02C0H MOV AX, 240H[BX] ; BX+240H=02C0H MOV AX, -0A0H[BP][SI] ; BP+SI-0A0H=0470H,默认 SS
第 6 题:写程序段
① 把标志寄存器中的 SF 置 1
LAHF OR AH,80H SAHF
② AL 中高、低 4 位互换
MOV CL,4 ROL AL,CL
或者:
MOV CL,4 ROR AL,CL
对于 8 位寄存器,循环移 4 位即可交换高低半字节。
③ AX、BX 组成 32 位带符号数,AX 为高 16 位,求其负数
原数为:AX:BX
求补码负数:
NEG BX ADC AX,0 NEG AX
④ 不用 ADD 和 ADC,实现 (A)+(B) → C
MOV AL,A MOV CL,B OR CL,CL JZ DONE NEXT: INC AL DEC CL JNZ NEXT DONE: MOV C,AL
⑤ 一条指令使 CX 中整数变为奇数
OR CX,1
如果原来是奇数,最低位已经是 1,不变;如果原来是偶数,最低位置 1,变成奇数。
第 7 题:写机器目标代码
① MOV BL,12H[SI]
机器码:8A 5C 12
② MOV 12H[SI],BL
机器码:88 5C 12
③ SAL DX,1
机器码:D1 E2
④ AND 0ABH[BP][DI],1234H
机器码:81 A3 AB 00 34 12
第 8 题:求 CL 和 AX
程序:
STR1 DW 'AB' STR2 DB 16 DUP(?) CNT EQU $ - STR1 MOV CX,CNT MOV AX,STR1 HLT
STR1 占 2 字节,STR2 占 16 字节,所以:
CNT = 18D = 12H
因此:CX = 0012H,CL = 12H
DW 'AB' 在内存中按字符顺序存放:41H,42H
按小端方式读入 AX:AX = 4241H
答案:CL = 12H,AX = 4241H
第 9 题:JMP FAR PTR ABCD 是什么转移方式?
JMP FAR PTR ABCD
这是:段间直接转移
也叫:远直接转移
因为目标地址的段地址和偏移地址直接由标号 ABCD 给出,执行后会同时修改:
CS 和 IP
第 10 题:写指令或程序段
① 使 AX 内容为 0
XOR AX,AX
② 使 BL 高、低 4 位互换
MOV CL,4 ROL BL,CL
③ 两个带符号数 X1、X2,求 X1 / X2
假设 X1、X2、Y1、Y2 都是字变量:
MOV AX,X1 CWD IDIV X2 MOV Y1,AX ; 商 MOV Y2,DX ; 余数
④ 屏蔽 BX 的 b4、b6、b11 位
要清零的位:
b4 = 0010H b6 = 0040H b11 = 0800H 合计 = 0850H(32位里面b4是第五位,b6是第7位也就是0000 0000 0100 0000对应0040H)
取反得到屏蔽码:F7AFH
指令:AND BX,0F7AFH
⑤ 将 AX 的 b4 到 b14 位取反,其他位不变
b4 到 b14 的掩码为:7FF0H
指令:XOR AX,7FF0H
⑥ 测试 DX 的 b0、b9 位是否为 1
如果要求两个位都为 1:
MOV AX,DX AND AX,0201H CMP AX,0201H JE BOTH_ONE
如果只是分别测试:
TEST DX,0001H ; 测试 b0 TEST DX,0200H ; 测试 b9
⑦ 使 CX 中整数变为奇数
OR CX,1
第 11 题:把 BLOCK 字数组第 6 个字送入 AX
第 6 个字相对首地址的偏移量:(6 - 1) × 2 = 10D = 0AH(地址1个字偏移2个字节)
① 寄存器间接寻址
LEA SI,BLOCK+0AH MOV AX,[SI]
② 直接寻址
MOV AX,BLOCK+0AH
③ 基址寻址
LEA BX,BLOCK+0AH MOV AX,[BX]
④ 基址变址相对寻址
LEA BX,BLOCK MOV SI,0 MOV AX,0AH[BX][SI]
第 12 题:SUB AX,BX 后 CF=1 说明什么?
SUB AX,BX
如果执行后:CF = 1说明在最高有效位发生了借位。
对无符号数来说,表示:AX < BX
所以无符号减法结果发生了下溢,结果按 16 位补码形式回卷保存。
第 13 题:JMP SHORT LAB 的目标地址
指令从 1000H 开始,短转移指令长度为 2 字节,所以转移位移是相对于:1002H
计算:
答案:
30H → 1032H 6CH → 106EH 0B8H → 0FBAH
第 14 题:求 ZF、PF、CF、SF
已知:
AL = 9AH = 1001 1010B BL = BCH = 1011 1100B
第 15 题:求独立执行结果
初始寄存器:
CS=3000H DS=2050H SS=50A0H ES=0FFFFH IP=0000H DI=000AH SI=0008H CX=FFFFH BX=0004H SP=2000H DX=17C6H , AX=8094H , BP=1403H , CF=1
内存:
20506H = 06H 20507H = 00H 20508H = 87H 20509H = 15H 2050AH = 37H 2050BH = C5H 2050CH = 2FH
① MOV DX,2[BX]
EA:BX + 2 = 0004H + 2 = 0006H
物理地址:DS × 10H + EA = 20500H + 0006H = 20506H
字数据:
[20506H] = 06H [20507H] = 00H
所以:DX = 0006H, BX = 0004H
② PUSH CX
SP = 2000H - 2 = 1FFEH [SS:SP] = FFFFH
③ MOV CX,BX
CX = 0004H BX = 0004H
④ TEST AX,01
TEST 不改变 AX,但会清 CF。
AX = 8094H CF = 0
⑤ MOV AL,[SI]
SI = 0008H 物理地址 = DS×10H + SI = 20508H [20508H] = 87H
所以:AL = 87H
初始寄存器:
CS=3000H DS=2050H SS=50A0H ES=0FFFFH IP=0000H DI=000AH SI=0008H CX=FFFFH BX=0004H SP=2000H
⑥ ADC AL,[DI],再执行 DAA
初始:
AL = 94H DI = 000AH [DI] = [2050AH] = 37H CF = 1
执行:ADC AL,[DI]
计算:94H + 37H + 1 = CCH
所以 ADC 后:AL = CCH,CF = 0
再执行:DAA
调整后:AL = 32H, CF = 1
⑦ INC SI
SI = 0009H
⑧ DEC DI
DI = 0009H
⑨ MOV [DI],AL
初始:
DI = 000AH AL = 94H
执行后:
[DS:DI] = [2050AH] = 94H DI = 000AH
⑩ XCHG AX,DX
初始:AX = 8094H , DX = 17C6H
交换后:AX = 17C6H , DX = 8094H
⑪ XOR AH,BL
初始:AH = 80H , BL = 04H
计算:80H XOR 04H = 84H
所以:AX = 8494H , BL = 04H
⑫ JMP DX
IP = DX = 17C6H AH = 80H
第 16 题:MOV AX,TABLE 和 LEA AX,TABLE
已知:TABLE 是数据段中 0032H 单元的符号名,其中内容为 1234H
执行:MOV AX,TABLE
得到的是内存内容:AX = 1234H
执行:LEA AX,TABLE
得到的是偏移地址:AX = 0032H
第 17 题:CALL FAR PTR OPRD 后 SP
已知:SP = 0FFFEH
远调用要压入:CS 和 IP
共 4 字节,所以:SP = 0FFFEH - 4 = 0FFFAH
第 18 题:数据区首字单元和第 32 个字单元地址
已知数据区起始地址:A7F0H:2B40H
物理地址:A7F0H × 10H + 2B40H = A7F00H + 2B40H = AAA40H
第 32 个字距离首字:(32 - 1) × 2 = 62D = 3EH
所以第 32 个字单元首地址:AAA40H + 3EH = AAA7EH
答案:
首字单元物理地址 = AAA40H 第 32 个字单元物理地址 = AAA7EH
如果问的是最后一个字节地址,则为:AAA7FH
第 19 题:堆栈操作
已知:
SP = 2000H AX = 3355H BX = 4466H
执行:
PUSH AX PUSH BX POP DX
过程:
PUSH AX:SP = 1FFEH,栈顶 = 3355H PUSH BX:SP = 1FFCH,栈顶 = 4466H POP DX :DX = 4466H,SP = 1FFEH
答案:
AX = 3355H DX = 4466H SP = 1FFEH
第 20 题:堆栈栈顶物理地址
已知:
SS = 2250H SP = 0140H
压入 5 个字数据:SP = 0140H - 5×2 = 0136H
栈顶物理地址:2250H×10H + 0136H = 22636H
再弹出 3 个字数据:SP = 0136H + 3×2 = 013CH
栈顶物理地址:2250H×10H + 013CH = 2263CH
答案:
压入 5 个数据后:22636H 再取出 3 个数据后:2263CH
第 21 题:指出程序段功能
①
MOV CX,10 LEA SI,FIRST LEA DI,SECOND REP MOVSB
功能:
把 DS:FIRST 开始的 10 个字节传送到 ES:SECOND 开始的内存区。
如果 DF=0,地址递增;如果 DF=1,地址递减。通常应提前加:
CLD
②
CLD LEA DI,[0404H] MOV CX,0080H XOR AX,AX REP STOSW
功能:从 ES:0404H 开始,把 0080H 个字单元清零。
也就是清零:80H 个字 = 128 个字 = 256 个字节
第 22 题:两种方法实现 SP = 27FEH
已知:SP = 2800H
方法一:SUB SP,2
方法二:PUSH AX
PUSH AX 会使:SP = SP - 2 = 27FEH
但会改变栈顶内存内容。
第 23 题:执行 CALL 2000:009AH
已知:
IP = 3D8FH CS = 4050H SP = 0F17CH
远调用指令长度为 5 字节,所以返回地址 IP:3D8FH + 5 = 3D94H
执行后跳到:
CS = 2000H IP = 009AH
远调用压入原来的 CS:IP,共 4 字节:SP = 0F17CH - 4 = 0F178H
栈中内容为小端存放:
[SP] = 94H [SP+1] = 3DH [SP+2] = 50H [SP+3] = 40H
答案:
IP = 009AH CS = 2000H SP = 0F178H [SP] = 94H [SP+1] = 3DH [SP+2] = 50H [SP+3] = 40H
第 24 题:写字符串传送程序
① 把 BUFFER1 的 100 个字节送到 BUFFER2
CLD LEA SI,BUFFER1 LEA DI,BUFFER2 MOV CX,100 REP MOVSB
如果 BUFFER2 在附加段,则目的地址为 ES:DI。
② 把 BLOCK1 的 100 个字送到同一数据段的 BLOCK2
因为 MOVSW 默认源是 DS:SI,目的为 ES:DI,若源和目的在同一数据段,应令:
ES = DS
程序:
PUSH DS POP ES CLD LEA SI,BLOCK1 LEA DI,BLOCK2 MOV CX,100 REP MOVSW
第 25 题:比较 DEST 和 SOURCE 中 500 个字节,找第一个不同字节
要求:若找到第一个不同字节,把 SOURCE 中这个字节送入 AL。
PUSH DS POP ES ; 假设 SOURCE 和 DEST 在同一数据段 CLD LEA SI,SOURCE LEA DI,DEST MOV CX,500 REPE CMPSB ; 相等则继续比较 JZ ALL_EQUAL ; CX=0 且未发现不同 MOV AL,[SI-1] ; SI 已经指向下一个字节,所以取 SI-1 ALL_EQUAL: HLT
第 26 题:在 100 个带符号字节中找最大值
LEA SI,BLOCK MOV CX,100 LODSB ; 取第一个数 MOV BL,AL ; BL 暂存当前最大值 DEC CX NEXT: LODSB CMP BL,AL ; 带符号比较 BL 和 AL JGE SKIP MOV BL,AL SKIP: LOOP NEXT MOV MAX,BL HLT
核心:
带符号数比较要用 JG、JGE、JL、JLE 不能用 JA、JB
第 27 题:指出 32 位指令源操作数寻址方式,并求执行后寄存器内容
①
LEA ECX,[EAX*2+14CH]
执行前:
EAX = 0548901AH
计算:
EA = EAX × 2 + 14CH = 0548901AH × 2 + 014CH = 0A912034H + 014CH = 0A912180H
答案:
寻址方式:带位移的比例变址寻址 ECX = 0A912180H EAX 不变
②
LEA EAX,TAB[EDX][4*ESI]
执行前:
ESI = 06533A44H EDX = 0892ABDFH TAB = 00000120H
计算:
EA = TAB + EDX + ESI × 4 = 00000120H + 0892ABDFH + 06533A44H × 4 = 21DF960FH
答案:
寻址方式:带位移的基址加比例变址寻址 EAX = 21DF960FH ESI、EDX 不变
③
MOV EAX,mem32
执行前:
[mem32] = 0892ABDFH
答案:
寻址方式:直接寻址 EAX = 0892ABDFH
④
PUSH 12345678H
32 位 PUSH 立即数时:
ESP ← ESP - 4 [SS:ESP] ← 12345678H
若题中给出:
ESP = FFFFF320H SS:[FFFFF31CH] = xxxxxxxxH
执行后:
ESP = FFFFF31CH SS:[FFFFF31CH] = 12345678H
小端存储时内存字节顺序为:
78H 56H 34H 12H
整体最容易错的是这几类:
1. 内存到内存通常不允许直接操作。 2. 8086 的移位次数只能是 1 或 CL。 3. 段寄存器不能随便作为目的操作数,例如 LEA DS,... 错。 4. PUSH/POP 在 8086 中只能是字操作。 5. 带 BP 的寻址默认段寄存器是 SS。 6. 字符串指令默认源 DS:SI,目的 ES:DI。
