← 返回 计组与微机控制

计组与微机控制

第七章习题

第七章习题

第 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。