第一章:掌握各进制的转换,有符号数的补码表示
1.1 各进制的转换
10进制 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16进制 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
A |
B |
C |
D |
E |
F |
2进制 |
0001 |
0010 |
0011 |
0100 |
0101 |
0110 |
0111 |
1000 |
1001 |
1010 |
1011 |
1100 |
1101 |
1110 |
1111 |
十进制数一般用D、二进制数用B、八进制数用O、十六进制数用H来表示。 例如:10101100B,115D ,0075H等。
例:
(1)N=45D 十进制数转换为二进制数(用除以2取余)
45/2 = 22 (a0= 1)
22/2 = 11 (a1= 0)
11/2 = 5 (a2= 1)
5/2 = 2 (a3= 1)
2/2 = 1 (a4= 0)
1/2 = 0 (a5= 1)
所以:N=45D=101101B
(2)N=117D 十进制转换为十六进制数(除以16取余法)
117/16 = 7 (a0= 5)
7/16 = 0 (a1= 7)
所以 :N=117D=75H
(3)将二进制数1011100转换为十进制数(各位二进制数码乘以与其对应的权之和)
1011100B = 1×2^6 + 0×2^5 + 1×2^4 + 1×2^3 + 1×2^2 + 0×2^1 + 0×2^0 = 92D
(4)将十六进制数3A4转换为十进制数(各位十六进制数码乘以与其对应的权之和)
3A4H = 3×16^2 + 10×16^1 + 4×16^0 = 932D
(5)将二进制数0011010110111111转换为十六进制数
解析:一个二进制数,把它从低位到高位每4位组成一组,直接用十六进制数来表示
0011 0101 1011 1111
3 5 B F
即:0011010110111111B = 35BFH
(6)把十六进制数A19C转换成相应的二进制数
解析:把十六进制数中的每一位用4位二进制数表示,就形成相应的二进制数
A 1 9 C
1010 0001 1001 1100
即:A19CH = 1010000110011100B
1.2 数的补码
正数(无符号数)来说,其二进制原码,反码,补码均为相同的,为原码的形式。
例:假设机器字长为8位,则[+1]补 = 00000001,[+127]补 = 01111111,[+0]补 = 00000000
负数(有符号数)的补码为对该数的原码除符号位外各位取反,然后在最后一位加1
例:机器字长为16位,写出N= -117D的补码表示
+117D可表示为: 0000 0000 0111 0101
按位求反后为 : 1111 1111 1000 1010
末位加1后 : 1111 1111 1000 1011
十六进制数为 : F F 8 B
即:[-117D]补 = FF8BH
1.3 符号扩展
常常需要把一个n位二进制数扩展成m位二进制数(m>n)。
当要扩展的数是无符号数时。只要在最高位前扩展(m-n)个0。
例:21的8位二进制和16位的二进制补码如下:
00010101 8位
0000000000010101 16位
如果要扩展的数是有符号数,并且采用补码形式表示,进行符号扩展。
例:-3的8位二进制补码和16位二进制补码如下:
11111101 8位
1111111111111101 16位
习题1.以下常用的十进制数转换为二进制数和十六进制数:
65535/2 = 32767 余1 255/2 = 127 余1
32767/2 = 16383 余1 127/2 = 63 余1
16383/2 = 8191 余1 63/2 = 31 余1
8191/2 = 4095 余1 31/2 = 15 余1
4095/2 = 2047 余1 15/2 = 7 余1
2047/2 = 1023 余1 7/2 = 3 余1
1023/2 = 511 余1 3/2 = 1 余1
511/2 = 255 余1 1/2 = 0 余1
65535D = 1111 1111 1111 1111 1111 = FFFF H
32767D = 0111 1111 1111 1111 1111 = 7FFF H
255D = 1111 1111 = FF H
习题2.十六进制数表示的8位二进制数,D8H和FFH,请说明当它们被看作是用补码表示的带符号数或无符号数时,它们所表示的十进制数是多少?
(1)D8H = 11011000B
无符号数时:1×2^7+1×2^6+1×2^4+1×2^3=216D
有符号数时: 11011000
按位取反 00100000
末位加1 00101000
此数为:40D
∴ D8H无符号数为216D;有符号数为-40D
(2)FFH = 1111 1111 B
无符号数时:1×2^7+1×2^6+1×2^5+1×2^4+1×2^3+1×2^2+1×2^1+1×2^0=255D
有符号数时:1111 1111
按位取反0000 0000
末位加10000 0001
∴ FFH无符号数为255D;有符号数为-1D
第二章 8086/8088寻址方式和指令系统
掌握各寄存器及寻址方式、以及数据传送指令、堆栈操作指令、加减、乘除运算指令、逻辑运算、移位指令和转移指令。
2.1 寄存器组
8位寄存器:AL、AH、BL、BH、CL、CH、DL、DH
16位寄存器:AX、BX、CX、DX、SI、DI、SP、BP、SI、DI、IP、FLAG、CS、DS、SS、ES
其中AX、BX、CX、DX可以分作高8位和低8位的两个独立寄存器。如:AH和AL。我们对其中8位的操作,并不影响另外对应的8位数据。
通用寄存器 |
数据寄存器 |
AH & AL = AX 累加寄存器 |
|
BH & BL = BX 基址寄存器 |
常用于地址索引 |
||
CH & CL = CX 计数寄存器 |
在移位指令,循环(loop)和串处理指令中用作隐含的计数器 |
||
DH & DL = DX 数据寄存器 |
|
||
指针寄存器 |
SP 堆栈指针寄存器 |
永远指向栈顶 |
|
BP 基址指针寄存器 |
|
||
变址寄存器 |
SI 源变址寄存器 |
|
|
DI 目的变址寄存器 |
|
||
|
|
||
|
控制寄存器 |
IP 指令指针寄存器 |
IP一般与CS连用 |
FLAG 标记寄存器 |
|
||
段寄存器 |
CS 代码段寄存器 |
|
|
DS 数据段寄存器 |
|
||
SS 堆栈段寄存器 |
|
||
ES 附加段寄存器 |
|
标志寄存器
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
|
|
|
OF |
DF |
IF |
TF |
SF |
ZF |
|
AF |
|
PF |
|
CF |
(1)运算结果标志
① 进位标志CF(Carry Flag):主要用于反映运算是否产生进位或借位。
② 零标志ZF(Zero Flag):反映运算结果是否为0。如果运算结果为0,则ZF被置1,否则置0。
③ 符号标志SF(Sign Flag):用于反映运算结果的符号位。
SF与运算结果的最高位相同,如果运算结果的最高位为1,则SF被置1,否则SF被置0。
④ 溢出标志OF(Overflow Flag):用于反映有符号数加减运算是否引出溢出。
如运算结果超出了8位或16位有符号数的表示范围,即在字节运算时大于 127 或小于-128,
在字运算时大于 32767 或小于-32768,称为溢出。如溢出,则OF被置1,否则被置0。
⑤ 奇偶标志PF(Parity Flag)
用于反映运算结果中“1”的个数。如果“1”的个数为偶数,则PF被置1; 否则PF被清0。
⑥ 辅助进位标志AF(Auxiliary Carry Flag)
在字或字节操作时,如发生低半字节向高半字节进位或借位,则辅助进位标志AF被置1,否则AF被清0。
(2)状态控制标志
① 方向标志DF(Direction Flag)
方向标志决定着串操作指令执行时有关指针寄存器调整方向。
当DF为1时,串操作指令按减方式改变有关的存储器指针值;
当DF为0时,串操作指令按加方式改变有关的存储器指针值。
② 中断允许标志IF(Interrupt - enable Flag)
中断允许标志决定着CPU是否响应外部可屏蔽中断请求。
当IF为1时,CPU能够响应外部的可屏蔽中断请求;
当IF为0时,则不响应外部的可屏蔽中断请求。
③ 追踪标志TF(Trap Flag)
当TF被置1后,CPU进入单步方式。所谓单步方式是指在一条指令执行后,产生一个单步中断。主要用于程序的调试。
2.2 物理地址
存储单元的逻辑地址由:段值和偏移两部分组成,用如下形式表示:段值:偏移
根据逻辑地址可方便地得到存储单元的物理地址,公式如下:
物理地址 = 段值×16(左移4位补0)+偏移
例:用16进制表示的逻辑地址1234:3456所对应的存储单元的物理地址为:
物理地址 = 12340 + 3456 = 15796H
2.3 寻址方式与物理地址计算
物理地址计算公式:物理地址=(DS/SS/ES) × 10H+(AX/BX/CX/DX/SI/DI/BP/SP)
立即寻址方式(无物理地址)
• 操作数作为指令的一部分。
• 立即数可以是8位可以是16位,立即数为16位时遵循“高高低低”原则。
• 低位字节存放在存储器低地址单元,高位字节存放在存储器高地址单元。
例:
8 位寄存器 MOV AH, 34H 则指令执行后,(AH)= 34H
16位寄存器 MOV AX, 1234H则指令执行后,(AX)= 1234H
寄存器寻址方式 (无物理地址)
• 操作数存放在寄存器中,通过指定寄存器来获取数据。
8 位寄存器 MOV AL, DH // 8 位寄存器与 8 位寄存器可传送
16位寄存器 MOV AX, SI // 16位寄存器与16位寄存器可传送
例:MOV AX,BX
若(AX)= 3064H,(BX)= 1234H;则指令执行后,(AX)=1234H,(BX)保持不变
直接寻址方式 (物理地址 = (DS)段地址 * 10H + 偏移地址)
• 指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址。
• 在通常情况下,操作数存放在数据段中。所以,默认情况下操作数的物理地址由数据段寄存器 DS 中的值和指令中给出的有效地址直接形成。
✯ 注意区别立即寻址和直接寻址书写表示方法上的不同,直接寻址的地址要放在方括号中。在源程序中,往往用变量名表示。
用符号地址代替数值地址,此时VALUE为存放操作数单元的符号地址。如下两者是等效的:
MOV AX, VALUE或MOV AX, [VALUE]
如VALUE在附加段(ES)中,则应指定段超越前缀。如下两者是等效的:
MOV AX, ES : VALUE 或 MOV AX, ES:[VALUE]
例:
MOV AX, [8054H]// 若(DS)=2000H,物理地址 = (DS) + 8054H = 20000H + 8054H = 28054H
MOV AH, VALUE // 将DS段中VALUE单元的内容送给AH
MOV BX, ES : [2000H] // 段超越,操作数在附加段。即:物理地址 = (ES) * 10H + 2000H
寄存器间接寻址方式
• 操作数有效地址在 SI 、 DI 、 BX、 BP 这四个寄存器之一中。
• 在不使用段超越前缀的情况下:
✯ 如果有效地址在 SI 、 DI 、 BX 中,则以数据段寄存器 DS 中的内容为段值。物理地址 = (DS) * 10H + (SI/DI/BX)
✯ 如果有效地址在 BP 中,则以堆栈段寄存器 SS 中的内容为段值。物理地址 = (SS) * 10H + (BP)
例:
MOV AX, [SI] // 若有效地址用SI、DI和BX等之一来指定,则其缺省的段寄存器为DS
设 (DS) = 5000H, (SI) = 1234H。 则物理地址 = (DS) × 10H+(SI) = 50000H + 1234H = 51234H
MOV DL, CS : [BX] // 物理地址 = CS * 10H + BX 段超越前缀,此时引用的段寄存器是CS而不是自动引用了DS
MOV AX, [BP] // 引用的段寄存器为SS
设 (SS)=3000H,(BP)=1000H。则物理地址 =(SS) × 10H+(BP) = 31000H
寄存器相对寻址方式 (物理地址 = (DS)*10H + 基址/变址 + 偏移量)
• 操作数的有效地址是一个基址寄存器( BX 、 BP )或变址寄存器( SI 、 DI )的值加上指令中给定的8位/16位偏移量之和。
即:EA(有效地址)= (BX/BP)/(SI/DI) + 8位位移量/16位位移量
• 在不使用段超越前缀的情况下:
✯ 如果有效地址在 SI 、 DI、 BX 中,则以段寄存器 DS 中的内容为段值
物理地址=(DS) * 10H+(BX/SI/DI)+8位位移量/16位位移量
✯ 如果有效地址在 BP 中,则以段寄存器 SS 中的内容为段值
物理地址=(SS) * 10H+(BP)+8位位移量/16位位移量
• 在指令中给定的8位或16位偏移量采用补码形式表示。在计算有效地址时,如偏移量是8位,则被带符号扩展成16位。
例:
MOV BX,[BP - 4]源操作数采用寄存器相对寻址,引用的段寄存器是SS
MOV ES : [BX + 5],AL 目的操作数采用寄存器相对寻址,引用的段寄存器是ES
以下书写方式是等价的:
MOV AX, [SI+3]
MOV AX, 3[SI]
习题:MOV AX,[DI + 1223H]
设 (DS) = 5000H,(DI) = 3678H。
则物理地址 = (DS) + (DI) + 1223H = 50000H + 3678H + 1223H = 5489BH
基址加变址寻址方式 (物理地址 = (DS)*10H + 基址 + 变址)
• 操作数的有效地址由基址寄存器( BX 、 BP )之一的值、变址寄存器( SI 、 DI )之一的值相加得到。
即:EA(有效地址) = (BX/BP) + (SI/DI)
• 在不使用段超越前缀的情况下:
✯ 如果有效地址在 SI 、 DI 、 BX 中,则以段寄存器 DS 中的内容为段值。
✯ 如果有效地址在 BP 中,则以段寄存器 SS 中的内容为段值。
MOV DS : [BP + SI], AL目的操作数采用基址加变址寻址,引用的段寄存器是DS
MOV AX, ES : [BX + SI]源操作数采用基址加变址寻址,引用的段寄存器是ES
以下三种书写方式是等价的:
MOV AX, [BX][SI] MOV AX, [BX + SI] MOV AX, [SI][BX]
例:MOV AX, [BX][DI]
设 (DS) = 2100H, (BX) = 0158H, (DI) = 10A5H。
则EA(有效地址) = 0158H + 10A5H = 11FDH;物理地址 = 21000H + 11FDH = 221FDH
相对基址加变址寻址方式 (物理地址 = (DS)*10H + 基址 + 变址 + 偏移量)
• 操作数的有效地址由基址寄存器( BX 、 BP )之一的值、变址寄存器( SI 、 DI )之一的值及指令中给定的8位/16位偏移量之和。
以下 4 种书写方式是等价的:
MOV AX, [BX+DI+1234H] MOV AX, 1234H[BX][DI] MOV AX, 1234H[BX+DI] MOV AX, 1234H[DI][BX]
例:MOV AX, [BX+SI+200H]
设(DS)=1000H,(BX)=2100H,(SI)=0010H,内存单元12310H的内容为1234H。问该指令执行后,AX的值是什么?
解:
有效地址EA = (BX) + (SI) + 200H = 2100 H+ 0010H + 200H = 2310H
物理地址PA = (DS) × 10H + EA=1000H × 10H + 2310H = 12310H
该指令的执行效果是:把从物理地址为12310H开始的一个字的值传送给AX,所以AX=12310H。
习题
1.现有(DS)=2000H,(BX)=0100H, (SI)=0002H, (20100)=12H, (20101)=34H, (20102)=56H,
(20103)=78H, (21200)=2AH, (21201)=4CH,(21202)=B7H, (21203)=65H
试说明下列各条指令执行完后AX寄存器的内容
(1) MOV AX, 1200H // (AX) = 1200H 立即寻址
(2) MOV AX, BX // (AX) = 0100H 寄存器寻址
(3) MOV AX, [1200H] // (AX) = 4C2AH 直接寻址
(4) MOV AX, [BX] // (AX) = 3412H 寄存器间接寻址
(5) MOV AX, 1100[BX] // (AX) = 4C2AH 寄存器相对寻址
(6) MOV AX,[BX][SI] // (AX) = 7856H 基址加变址寻址
(7) MOV AX, 1100[BX][SI] // (AX) = 65B7H 相对基址加变址寻址
2.假设(DS)=2000H, (ES)=2100H, (SS)=1500H, (SI)=00A0H, (BX)=0100H,(BP)=0010H,数据段中变量名VAL的偏移地址值为0050H, 试指出下列源操作数字段的寻址方式及物理地址值是多少?
(1) MOV AX, 0ABH // 立即寻址,无物理地址
(2) MOV AX, BX // 寄存器寻址,无物理地址 (AX)=0100H
(3) MOV AX, [100H] // 直接寻址,物理地址 = (DS) × 10H +100H = 20100H
(4) MOV AX, VAL // 直接寻址,物理地址 = (DS) × 10H +VAL = 20050H
(5) MOV AX, [BX] // 寄存器间接寻址,物理地址 = (DS)×10H + BX = 20100H
(6) MOV AX, ES:[BX] // 段跨越前缀寄存器间接寻址,物理地址 = (ES)×10H + BX = 21100H
(7) MOV AX, [BP] // 寄存器间接寻址,物理地址 = (SS)×10H + BP = 15010H
(8) MOV AX, [SI] // 寄存器间接寻址,物理地址 = (DS)×10H + SI = 200A0H
(9) MOV AX, [BX+10] // 寄存器相对寻址,物理地址 = (DS)×10H + BX + 10H = 20110H
(10) MOV AX,VAL[BX] // 寄存器相对寻址,物理地址 = (DS)×10H + BX + VAL = 21050H
(11) MOV AX, [BX][SI] // 基址加变址寻址,物理地址 = (DS)×10H + BX + SI = 210A0H
(12) MOV AX, VAL[BX][SI] // 相对基址加变址寻址
物理地址 = (DS)×10H + VAL+ BX + SI = 20000H + 0050H + 0100H + 00A0H = 210F0H
2.4 8086/8088指令系统
传送指令 不影响标志位
格式:MOV DST,SRC
(1)CPU内部寄存器之间的数据传送。
例如:MOV AH, AL MOV BP, SP MOV AX, CS
✯ 源和目的操作数不能同时是段寄存器。 如:MOV DS, ES
✯ 代码段寄存器CS不能作为目的操作数。 如:MOV CS, AX
✯ 指令指针IP既不能作为源操作数,也不能作为目的操作数。
(2)立即数送至通用寄存器或存储单元(各种存储器寻址方式)。
✯ 立即数不能直接传送到段寄存器。 如:MOV DS, 3
✯ 立即数永远不能作为目的操作数。
(3)寄存器与存储器间的数据传送。
✯ 源操作数和目的操作数类型要一致,即源操作数目的操作数都是8位寄存器或者16位寄存器。
✯ 除了串操作指令外,源操作数和目的操作数不能同时是存储器操作数。
如果要在两个 存储单元间 或 段寄存器间 传送数据,那么可利用通用寄存器过渡的方法进行。
例1:把字变量VARW1的内容送到字变量VARW2
MOV AX,VARW1 // 先把VARW1的内容送到AX
MOV VARW2,AX // 先把CS的内容送到VARW2
例2:把CS的内容送到DS
MOV AX,CS // 先把CS的内容送到AX
MOV DS,AX // 再把AX的内容送到DS
交换指令 不影响标志位
概述:方便地实现 通用寄存器 与 通用寄存器 或 存储单元 间 的数据交换
格式:XCHG OPRD1,OPRD2
✯ 源操作数和目的操作数必须同时是字节或字。 如:XCHG AL, AH XCHG SI, BX
✯ 两个操作数可以是通用寄存器和存储单元。但不包括段寄存器,也不能同时是存储单元也不能有立即数。 如:XCHG AX, VARW XCHG AX, 1234H
例:XCHG BX, [BP+SI]
设(BX)=6F30H, (BP)=0200H, (SI)=0046H, (SS)=2F00H, (2F246)=4154H
物理地址 = SS * 10H + BP + SI = 2F000 + 0200 + 0046 = 2F246H
指令执行后: (BX)=4154H (2F246H)=6F30H(BX的内容送到2F246H中)
地址传送指令 不影响标志位
(1)指令LEA(Load Effective Address)
格式: LEA REG,OPRD
指令LEA称为传送有效地址指令,该指令把操作数OPRD的有效地址传送到操作数REG。
✯ 操作数OPRD必须是一个存储器操作数。
✯ 操作数REG必须是一个16位的通用寄存器。
例: LEA BX, [BX+SI+0F62H]相对基址加变址寻址
设指令执行前 (BX)=0400H, (SI)=003CH
指令执行后 (BX) = BX + SI + 0F62H = 0040H + 003CH + 0F62H = 139EH
(2)指令LDS(Load pointer into DS)
段值和段内偏移构成32位的地址指针。该指令传送32位地址指针到数据段寄存器DS。
格式:LDS REG,OPRD
执行的操作:
REG ← OPRD // 把偏移部分送到指令给出的通用寄存器REG
DS ← OPRD+2 // 把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS
✯ 目的操作数OPRD必须是一个32位的存储器操作数。
✯ 源操作数REG可以是一个16位的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。
例:LDS SI, [ 10H ]
设指令执行前: (DS)= C000H, (C0010H)= 0180H, (C0012H)= 2000H
指令执行后: (SI)= 0180H, (DS)= 2000H
(3)指令LES(Load pointer into ES)
该指令传送32位地址指针到附加段寄存器ES。
格式:LES REG,OPRD
执行的操作:
REG ← OPRD // 把偏移部分送到指令给出的通用寄存器REG
ES ← OPRD+2 // 把操作数OPRD中所含的一个32位地址指针的段值部分送到附加段寄存器ES
例如: LES DI, [ BX ]
如指令执行前:(DS)=B000H,(BX)=080AH,(0B080AH)=05AEH,(0B080CH)=4000H
指令执行后:(DI)= DS × 10H + BX = 0B080AH = 05AEH , (ES)= 4000H
习题
1. 如TABLE为数据段中0032单元的符号名,其中存放的内容为1234H,试问以下指令有什么区别?指令执行完后AX寄存器的内容是什么?
MOV AX, TABLE // 直接寻址,把TABLE内容传送给AX。 (AX)= 1234H
LEA AX, TABLE // 将TABLE有效地址与AX交换。(AX)= 0032H
MOV AX,OFFSET TABLE // 将TABLE有效地址传送给AX。(AX)= 0032H
2. 一个有16个字的的数据区,它的起始地址为70A0:DDF6,请写出这个数据区首末字单元的物理地址。
首地址为:70A00 + DDF6 = 7E7F6H
末地址为:7E7F6 + 1E = 7E814H
因为是16个字,32个字节,首末中间隔着30个字节,末地址 = 首地址 + 1E(30的16进制数)
堆栈操作指令 不影响标志位 后进先出
堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶。
堆栈的存取必须以字为单位。
(1)进栈指令PUSH
格式:PUSH SRC
执行的操作: (SP) ← (SP)-2
该指令把源操作数SRC压入堆栈。它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指的栈顶。
✯ 源操作数SRC可以是通用寄存器和段寄存器,也可以是字存储单元。
例:PUSH AX PUSH DS PUSH VARW PUSH [SI]
(2)出栈指令POP
格式:POP DST// DST可以是通用寄存器和段寄存器(但CS例外),也可以是字存储单元。
执行的操作: (SP) ← (SP) + 2
该指令从栈顶弹出一个字数据到目的操作数DST。它先把堆栈指针寄存器SP所指的字数据送至目的的操作数DST,然后SP值加2。
✯ 以上两条指令PHSH和POP只能作字操作。
✯ 它们可以使用除立即数以外的其他寻址方式。
✯ POP指令不允许用CS寄存器。
数据交换的三种方式:传送指令、交换指令、堆栈指令
扩展:将寄存器AX与SI的内容交换
(1)MOV指令,利用通用寄存器过渡的方法
MOV BX, AX
MOV AX, SI
MOV SI, BX
(2)用交换指令XCHG
XCHG AX, SI
(3)用堆栈指令:临时保存寄存器的内容
PUSH AX
PUSH SI
……
POP AX ;使AX内容与SI相同
POP SI
习题:假设(SS)= 2250H,(SP)= 0140H,如果在堆栈中存入5个数据,则栈顶的物理地址为多少?如果又从堆栈中取出3个数据,则栈顶的物理地址是多少?
解:未存入数据之前物理地址 = 22500 + 0140 = 22640H
存入5个数据栈顶的物理地址为:22640 - 0A = 22636H
取出3个数据栈顶的物理地址为:22636 + 6 = 2263CH
标志操作指令
(1)标志传送指令
① 指令LAHF(Load AH with Flags)
指令LAHF采用固定寻址方式,格式:LAHF
该条指令把标志寄存器的低8位(包括SF、ZF、AF、PF和CF)传送到寄存器AH的指定位。
这条指令本身不影响这些标志和其他标志。
② 指令SAHF (Store AH into Flags)
指令SAHF采用固定寻址方式,格式:SAHF
该条指令与指令LAHF刚好相反,把寄存器AH的指定位送至标志寄存器低8位的SF、ZF、AF、PF和CF标志位。因而这些标志的内容就要受到影响,并取决于AH中相应位的状态。
但这条指令不影响溢出标志OF、方向标志DF、中断允许标志IF和追踪标志TF,也即不影响标志寄存器的高位字节。
例如:
MOV AH,0C1H
SAHF ;CF=1,PF=0,AF=0,ZF=1,SF=1
如图所示: 7 6 5 4 3 2 1 0
AH |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
↓ ↓ ↓ ↓ ↓
|
|
|
|
OF |
DF |
IF |
TF |
SF |
ZF |
|
AF |
|
PF |
|
CF |
③ 指令PUSHF
格式:PUSHF
该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶。
④ 指令POPF
格式: POPF
该条指令把当前堆栈顶的一个字传送到标志寄存器,同时相应地修改堆栈指针,即把堆栈指针寄存器SP的值加2。
POPF和PUSHF指令一起可以保存和恢复标志寄存器的内容,即保存和恢复各标志的值。另外,这两条指令也可以用来改变追踪标志TF。
(2)标志位操作指令 仅对指令规定的标志,产生指令规定的影响
① 清进位标志指令CLC(Clear Carry flag)
格式:CLC 该指令使进位标志为0。
② 置进位标志指令STC(SeT Carry flag)
格式:STC 该指令使进位标志为1。
③ 进位标志取反指令CMC(CoMplement carry flag)
格式:CMC 该指令使进位标志取反。如CF为1,则使CF为0;如CF为0,则使CF为1。
④ 清方向标志CLD(Clear Direction flag)
格式:CLD 该条指令使方向标志DF为0。
从而在执行串操作指令时,使地址按递增方式变化。
⑤ 置方向标志STD(SeT Direction flag)
格式:STD 该条指令使方向标志DF为1。
从而在执行串操作指令时,使地址按递减方式变化。
⑥ 清中断允许标志CLI(Clear Interrupt enable flag)
格式: CLI 该条指令使中断允许标志IF为0,于是CPU就不响应来自外部装置的可屏蔽中断。
但对不可屏蔽中断和内部中断都没有影响。
⑦ 置中断允许标志STI(SeT Interrupt enable flag)
格式:STI 该条指令使中断允许标志IF为1,则CPU可以响应可屏蔽中断。
习题:设当前数据段寄存器的内容为1B00H,在数据段的偏移地址2000H单元内,含有一个内容为0FF10H和8000H的指针,它们是一个16位变量的偏移地址和段地址,试写出把该变量装入AX的指令序列。
根据题意可得:(DS)=1B00H, 偏移地址2000H, 段地址8000H: FF10H
物理地址 = 1B000H + 2000H = 1D000H, (1D000H)=0FF10H, (1D002H)=8000H
MOV BX, [2000H] // (BX) = 0FF10H
MOV ES, [2002H] // (ES) = 8000H
MOV AX, ES:[BX]
加法指令 影响标志位
(1)普通加法指令 ADD
格式:ADD OPRD1, OPRD2
执行的操作: (OPRD1) ← (OPRD1) + (OPRD2)
例1:
MOV AX,7896H ; AX=7896H,即AH=78H,AL=96H;各标志位保持不变
ADD AL,AH ;AL=0EH,AH=78H,即AX=780EH; CF=1,ZF=0,SF=0,OF=0,AF=0,PF=0
例2: ADD DX, 0F0F0H 执行前 ( DX ) = 4652H
执行后 ( DX ) = 3742H, ZF=0,SF=0,CF=1,OF=0
例3:ADD AX, 4321 执行前 (AX) = 62A0H
执行后 (AX) = A5C1H SF=1,ZF=0,CF=0,OF=1
SF 符号标志位根据运算结果最高位决定,若最高位为0则是正数,则SF=0,否则SP=1。如例3 结果最高位是A-1010,第一位是1,表示负数,所以SF=1。
OF 溢出标志位根据操作数的符号及其变化情况来设置,若两个操作数的符号相同而结果的符号与之相反时OF=1,否则OF=0。如例3 正数加正数结果为负数,则溢出OF=1。
(2)带进位加法指令 ADC
格式:ADC OPRD1, OPRD2
执行的操作:(OPRD1) ← (OPRD1) + (OPRD2) + CF
例:下列指令序列执行两个双精度的加法。
设目的操作数放在DX和AX寄存器中,其中DX存放高位字。源操作数存放在BX、CX中,其中BX存放高位字。如指令执行前:(DX)=0002H, (AX)=0F365H,(BX)=0005H, (CX)=0E024H
指令序列为: ADD AX,CX
ADC DX,BX
执行第一条指令后:
(AX)= (AX) + (CX) = 0F365H + 0E024H = 0D389H, SF=1,ZF=0,CF=1,OF=0
执行第二条指令后:
(DX)= (DX) + (BX) + CF = 0002H + 0005H + 0 = 0007H,SF=0,ZF=0,CF=0,OF=0
则该指令序列执行完后: (DX)=0008H,(AX)=D389H
(3)加1指令 INC
格式:INC OPRD
执行的操作:OPRD ← OPRD + 1
这条指令执行的结果影响标志ZF、SF、OF、PF和AF,但它不影响CF。
例1:写出把首地址为BLOCK的字数组的第6个字送到DX寄存器的指令.
要求使用以下几种寻址方式:
(1) 寄存器间接寻址
MOV BX, OFFSET BLOCK
ADD BX, 000AH ;10个字节
MOV DX, [ BX ]
(2) 寄存器相对寻址
MOV BX, OFFSET BLOCK
MOV DX, [ BX+000AH ]
例2:在TABLE数组中依次存储了七个字数据,紧接着是名为ZERO的字单元,表示如下:
TABLE DW 23, 36, 2, 100, 32000, 54, 0
ZERO DW ?
(1) 如果BX包含数组TABLE的初始地址,请编写指令将数据0传送给ZERO单元.
MOV AX , [ BX+0CH ]
MOV ZERO, AX
(2) 如果BX包含数据0在数组中的位移量,请编写指令将数据0传送给ZERO单元
MOV AX, [ TABLE +BX ]
MOV ZERO, AX.
减法指令
减法的OF位:若两个数的符号相反(异号相减), 而结果的符号与减数相同则OF=1.
(1)普通减法指令 SUB
格式:SUB OPRD1, OPRD2
执行的操作: (OPRD1) ← (OPRD1) - (OPRD2)
例1:SUB [ SI+14H ] , 0136H
指令执行前 (DS)=3000H , (SI)=0040H,(30054H)=4336
指令执行后 (30054H)=4200H SF=0 , ZF=0 , CF=0 , OF=0
例2:SUB DH, [ BP+4 ]
指令执行前 (DH)=41H , (SS)=0000H , (BP)=00E4H , (000E8H)=5AH
指令执行后 (DH)=0E7H , SF=1 , ZF=0 , CF=1, OF=0
(2)带借位减法指令 SBB
格式:SBB OPRD1, OPRD2
执行的操作: (OPRD1) ← (OPRD1) - (OPRD2) - CF
(3)减1指令 DEC
格式:DEC OPRD
执行的操作: (OPRD) ← (OPRD) - 1
(4)取补指令 NEG(NEGate)
格式:NEG OPRD
执行的操作: (OPRD) ← -(OPRD)
如在字节操作时对-128取补,或在字操作时对-32768取补,则操作数不变,但OF被置1。其它均为0
操作数为0时,求补运算的结果使CF=0,其它情况则均为1。
(4)比较指令 CMP(CoMPare)
格式:CMP OPRD1,OPRD2
这条指令完成操作数OPRD1减去操作数OPRD2,运算结果不送到OPRD1,
但影响标志CF、ZF、SF、OF、AF和PF。
执行了比较指令后,可根据ZF是否置位,判断两者是否相等;
如果两者是无符号数,则可根据CF判断大小;
如果两者是有符号数,则要根据SF和OF判断大小。
习1:设X\Y\Z均为双精度数,它们分别存放在地址为X, X+2; Y, Y+2; Z, Z+2的存储单元中,存放时高位字在高地址中,低位字在低地址中。用指令实现W←X+Y+24-Z并用W和W+2单元存放运算结果。
MOV AX, X MOV DX, X+2
ADD AX, Y ADC DX, Y+2 ;低位加完要考虑有没有进位
ADD AX, 24 ADC DX, 0 ;低位加完要考虑有没有进位
SUB AX, Z SBB DX, Z+2
MOV W, AX MOV W+2, DX
习2:写出执行以下计算的指令序列,其中X, W, Z均为存放16位带符号数单元的地址。
Z←W + (Z-X)
MOV AX, Z SUB AX, X ADD AX, W MOV Z, AX
习3:写出对存放在DX和AX中的双字长数求补的指令序列
NEG DX ;先对高位DX求补
NEG AX ;再对地位AX求补
SBB DX,0 ;再看有没有借位
乘法指令
(1)无符号数乘法指令 MUL(MULtiply)
格式:MUL OPRD
隐含的目的操作数必须是累加器。
若OPRD是字节操作数,则把AL中的无符号数与OPRD相乘,16位结果送到AX中;若OPRD是字操作数,则把AX中的无符号数与OPRD相乘,32位结果送到DX(高16位)和AX(低16位)中。
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不等于零,则标志CF= OF=1(如:1234);否则CF= OF=0(如:0014)。所以如果CF=1和OF=1表示在AH或DX中含有结果的有效数。
(2)有符号数乘法指令 IMUL(sIgned MULtiply)
格式:IMUL OPRD
如果乘积结果的高半部分(字节相乘时为AH,在字相乘时为DX)不是低半部分的符号扩展,则标志CF=1,OF=1;否则CF=0,OF=0(如:FFBB/0014)。
例:如(AL)=0B4H,(BL)=11H 求执行指令 IMUL BL 和 MUL BL 后的乘积值
(AL) = 0B4H 为无符号的180D,带符号数的-76D(取反+1)
(BL) = 11H 为无符号的17D,带符号数的17D
执行 MUL BL 的结果为 (AX)= 0B4H × 11H = 0BF4H = 3060D CF=OF=1
执行 IMUL BL 的结果为 (AX)= 0FFB4H × 11H = 0FAF4H = -1292D CF=OF=1
除法指令
(1)无符号数除法指令 DIV(DIVersion)
格式:DIV OPRD
字节操作表示为: ( AL ) → (AX) / (OPRD) 的商;(AH) → ( AX) / (OPRD) 的余数
字操作表示为:( AX ) → (DX,AX) / (OPRD) 的商;(DX) → ( DX,AX ) / (OPRD) 的余数
如果除数为0,或者在8位数除时商超过8位。或者在16位除时商超过16位,则认为是除溢出,引起0号中断。
(2)有符号数除法指令 IDIV(sIgned DIVersion)
格式:IDIV OPRD
例:设(AX)= 0400H,(BL)= 0B4H
即(AX)为无符号数的1024D,带符号数的1024D
(BL)为无符号数的 180 D,带符号数的-76D
执行 DIV BL 的结果是:(AH)= 0400H % 007CH = 124D 余数 (AL)=05H=5D 商
执行 IDIV BL 的结果是:(AH)=24H=36D 余数 (AL)=0F3H= -13D 商
符号扩展指令 不影响各标志位
由于除法指令隐含使用字被除数或双字被除数,所以当被除数为字节,或者除数和被除数均为字时,需要在除操作前扩展被除数。
(1)字节转换为字指令 CBW(Convert Byte to Word)
格式:CBW // 指令把寄存器AL中的符号扩展到寄存器AH
例:MOV AX,3487H ;AX=3487H,即AH=34H,AL=87H
CBW ;AH=0FFH,AL=87H,即AX=0FF87H
10000111 8 位 // 扩充前:78H
11111111 10000111 16位 // 扩充后:FF87H
(2)字转换为双字指令 CWD(Convert Word to Double word )
格式:CWD // 指令把寄存器AX中的符号扩展到寄存器DX
例: MOV AX,4567H ;AX=4567H
CWD ;AX=4567H,DX=0
01000101 01100111 16位 // 扩充前:4567H
00000000 00000000 01000101 01100111 32位 // 扩充后:AX = 4567H, DX = 0H
习题:计算如下表达式的值:(X*Y+Z-1024)/75。假设其中的X、Y和Z均为16位带符号数,分别存放在名为XXX、YYY和ZZZ的变量单元中。再假设计算结果的商保存在AX中,余数保存在DX中。
MOV AX,XXX
IMUL YYY ;计算X*Y,带符号 16位*16位=32位
MOV CX,AX
MOV BX,DX ;积保存到BX:CX中
MOV AX,ZZZ
CWD ;把ZZZ扩展成32位(AX扩展成DX)
ADD AX,CX ;再计算和
ADC DX,BX
SUB AX,1024 ;再计算差
SBB DX,0
MOV CX,75
IDIV CX ;最后计算商和余数
逻辑指令
(1)否操作指令 NOT
格式: NOT OPRD// 该指令把操作数OPRD取反,然后送回OPRD。
操作数OPRD可以是通用寄存器,也可以是存储器操作数。此指令对标志没有影响。
例:NOT AL 设 (AL) = 34H 00110100B 取反 11001011 ∴ (AL) = CBH
(2)与操作指令AND
格式:AND OPRD1,OPRD2;CF=0,OF=0
该指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。
某个操作数自己与自己相“与”,则值不变,但可使进位标志CF清0。
参与运算的两个数据同时为1,则结果值为1。否则为0
例:AND AL, 0FH 设 (AL) = 34H 执行指令后:(AL) = 04H
34H --- 00110100B
0FH --- 00001111B
______________________
00000100B --- 04H
(3)或操作指令OR
格式:OR OPRD1,OPRD2
这条指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。
某个操作数自己与自己相“或”,则值不变,但可使进位标志CF清0。
参与运算的两个数据只要有一个值为1,那么结果值为1
例:OR AL, 20H 设 (AL) = 41H 执行指令后:(AL) = 61H
41H --- 01000001B
20H --- 00100000B
______________________
01100001B ---61H
(4)异或操作指令 XOR
格式:XOR OPRD1,OPRD2
该指令执行以后,标志CF=0,标志OF=0,标志PF、ZF、SF反映运算结果,标志AF未定义。
某个操作数自己与自己相“异或”,则结果为0,并可使进位标志CF清0。
参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
例:XOR AL, 0FH 设 (AL) = 34H 执行指令后:(AL) = 3BH
34H --- 00110100B
0FH --- 00001111B
______________________
00111011B --- 3BH
(5)测试指令 TEST
格式:TEST OPRD1,OPRD2
该指令和指令AND类似,也把两个操作数进行按位“与”,但结果不送到操作数OPRD1。
该指令执行以后,标志ZF、PF和SF反映运算结果,标志CF和OF被清0。
例:要检查AL中的位6或位2是否有一位为1,可使用如下的指令:
TEST AL,01000100B ;符号B表示二进制
如果位6和位2全为0,那么在执行上面的指令后,ZF被置1,否则ZF被清0。
习题1:要求屏蔽0、1两位。
解析:即将第0位、第1位置0。可用AND指令,若要使某位变0则让其和“0”相与,其余和“1”相与
MOV AL, 0BFH BFH --- 10111111
ADD AL, 0FCHADD ∴ 11111100 --- FCH
∴ (AL) = 0BCH 期望结果 10111100 --- BCH
习题2:要求第5位置1。
解析:可用OR指令,若要使某位变1则让其和“1”相或,其余和“0”相或
MOV AX 43H01000001
OR AX 20H OR 00100000
∴ (AL) = 63H01100001
习题3:如要测试AL寄存器中第2位 是否为1,如为1则转移到EXIT去执行。
解析:要测试操作数的某位是否为1,则可先把该操作数求反,然后用TEST指令测试。
MOV DL,AL
NOT DL ;取反
TEST DL,00000100B ;测试第2位是否为1
JE EXIT
一般移位指令
如果移位数m=1,可以直接跟在操作指令后(如:SHL AL, 1)
如果位移数m>1,必须先将m存放在CL寄存器中(如:MOV CL, m)
(1)算术左移或逻辑左移指令SAL/SHL(Shift Arithmetic Letf / Shift logic Left)
格式:SAL OPRD,m / SHL OPRD,m
算术左移SAL/逻辑左移SHL指令把操作数OPRD左移m ,每移动一位,右边用0补足一位,移出的最高位进入标志位CF。
只要左移以后的结果未超出一个字节或一个字的表达范围,那么每左移一次,原操作数每一位的权增加了一倍,也即相当于原数乘2。
逻辑左移SHL1位 → 无符号数 * 2
算术左移SHL1位 → 有符号数 * 2
例1:MOV AL,8CH ;8CH -- 10001100B
SHL AL,1 ;左移1位00011000B,AL=18H。CF=1,PF=1,ZF=0,SF=0,OF=1
MOV CL,6 ;CL=6。如果移位是1可以直接写SHL AL,1。大于1都要先传送到CL
SHL AL,CL ;AL左移6位,AL=0。CF=0,PF=1,ZF=1,SF=0,OF=0
OF 移位次数为1时才有效,左移前后最高位是否发生改变。若改变则OF = 1;否则OF = 0.
习题:实现把寄存器AL中的内容(设为无符号数)乘10,结果存放在AX中。
XOR AH,AH ;(AX)=0 因为是AL寄存器,将AH清零
SHL AL,1 ;2X
MOV BX,AX ;暂存2X
SHL AX,1 ;4X
SHL AX,1 ;8X
ADD AX,BX ;8X+2X
(2)算术右移指令SAR(Shift Arithmetic Right)
格式: SAR OPRD,m // 算术右移一位相当于自身除以2
该指令使操作数右移m位,同时每移一位,左边的符号位保持不变,移出的最低位进入标志位CF。
算术右移指令SAR看最高有效位。若最高有效位为1,则右移补1。
例1:MOV CL , 5
SAR [ DI ] , CL
如指令执行前: ( DS )=0F800H, (DI)=180AH, (0F980A)=0064H
解:物理地址 = (DS) + (DI) = 0F980AH 对 0F980A 右移5位
指令执行后: (0F980A)=0003H,CF=0
例2:MOV DH, 0B9H MOV CL, 3 SAR DH, CL 执行后(DH)=0F7H
B9H --- 10111001B
右移3位 --- 11110111B -- 0F7H
(3)逻辑右移指令SHR(Shift logic Right)
逻辑右移指令的格式如下:
格式: SHR OPRD,m // 对于无符号数而言,逻辑右移一位相当于除以2。
该指令使操作数右移m位,同时每移一位,左边用0补足,移出的最低位进入标志位CF。
例:假设DATA1和DATA2各长4位,分别存放在AL寄存器的低4位和高4位中,现要把它们分别存放到BL寄存器和BH寄存器的低4位中。
解析:(AL) =DATA2DATA1
MOV BL,AL
AND BL,0FH ;低4位和“1”相与,得DATA1
MOV BH,AL
MOV CL,4
SHR BH,CL ;逻辑右移4位(无符号数),得DATA2
循环移位指令 只影响标志CF和OF
格式:
ROL OPRD,m;循环左移
ROR OPRD,m;循环右移
RCL OPRD,m;带进位循环左移
RCR OPRD,m;带进位循环右移
操作数OPRD可以是通用寄存器,可以是存储器操作数。
循环左移ROL:每移位一次操作数左移,最高位进入最低位,CF即最低位。
循环右移ROR:每移位一次操作数右移,最低位进入最高位,CF即最高位。
RCL:CF移入最高位参与运算(共9位),每移位一次操作数左移,最高位进入最低位,CF即最高位。
RCR:CF移入最低位参与运算(共9位),每移位一次操作数右移,最低位进入最高位,CF即最低位。
例:MOV AL, 34H MOV CL, 3
(1)ROL AL, CL;执行命令后(AL) = 0A1H
(2)ROR AL, CL;执行命令后(AL) = 86H
(3)RCL AL, CL;设CF = 1。执行命令后(AL) =1DH
(4)RCR AL, CL;设CF = 1。执行命令后(AL) =4DH,CF = 1
34H --------- 00110100B
ROL --------- 10100001B -- 循环左移3位后:0A1H,CF=1
ROR --------- 10000110B -- 循环右移3位后:86H,CF=1
RCL移动前 --- 101000011B -- CF加入最高位参与运算
RCL移动后 ----000011101B -- 带进位循环左移3位后:1DH,CF = 0
RCR移动前 --- 001101001B -- CF加入最低位参与运算
RCR移动后 ----010011010B -- 带进位循环右移3位后:4DH,CF = 0
习题1:(AX)=0012H, (BX)=0034H,要求把它们装配在一起形成(AX)=1234H
MOV CL, 8 ;注意是16位寄存器
ROL AX, CL
AND AX, BX
习题2:试分析下面的程序段完成什么功能。
MOV CL ,4 ;(CL)= 4
SHL DX ,CL ;DX逻辑左移4位
MOV BL , AH ;(BL) = (AH) BX低8位等于AX高8位
SHL AX , CL ;AX逻辑左移4位
SHR BL , CL ;BL逻辑右移4位
OR DL , BL ;
DX:8765 -- 左移4位7650 --- OR DL, BL (DL) = 54 (DX)=7654
AX:4321 -- 左移4位3210
BL:BL= AX = 43 ---- 右移4位04
该程序功能:把AX,DX中双字左移4位
习题3:现有程序的如下:
XOR AX, AX ;(AX) = 0,CF = 0
MOV AX, 6C5AH ;(AX) = 6C5AH,(AH) = 6CH,(AL) = 5AH
MOV CX, 0203H ;(CX) = 0203H,(CH) = 02H,(CL) = 03H
RCL AH, CL ;(CL) = 3, CF= 0,AH带位左循环位移3位。(AH) = 61H,CF= 1
XCHG CH,CL ;CH、CL交换,(CH) = 03H,(CL) = 02H
RCR AL,CL ;(CL) = 2, CF= 0,AL带位右循环位移2位。(AL) = 56H,CF= 1
HLT ;停机
求(AX) = 6156H ,(CF)= 1 ,(CX)= 0302H 。
转移指令
1. 无条件转移指令
① 无条件段内直接转移指令
格式:JMP 标号;该指令使控制无条件地转移到标号地址处
把指令中的地址差加到指令指针IP上,使IP之内容为目标地址,从而达到转移的目的。
例:
NEXT: MOV AX,CX
……
JMP NEXT ;转NEXT处
……
JMP OVER ;转OVER处
……
OVER: MOV AX,1
② 无条件段内间接转移指令
格式:JMP OPRD;使控制无条件地转移到操作数由OPRD的内容给定的目标地址
操作数OPRD可以是通用寄存器,也可以是字存储单元。
例: JMP WORD PTR [1234H] ;
③ 无条件段间直接转移指令
格式:JMP FAR PTR 标号;把指令中包含的目标地址的段值和偏移分别置入CS和IP
标号前的符号 “FAR PTR”向汇编程序说明这是段间转移。
例:JMP FAR PTR EXIT ;EXIT是定义在另一个代码段中的标号
④ 无条件段间间接转移指令
格式:JMP OPRD;操作数OPRD必须是双字存储单元。
该指令使控制无条件地转移到由操作数OPRD的内容给定的目标地址处。
例:JMP DWORD PTR [1234H] ;双字存储单元的低字内容送IP,高字内容送CS
习题: (IP)=2BC0H,(CS)=0200H,位移量D=5119H,(BX)=1200H,(DS)= 212AH,(224A0)=0600H,(275B9)=098AH,试为以下的转移指令找出转移的偏移地址。
(1)段内直接寻址
(2)使用BX及寄存器间接寻址方式的段内间接寻址
(3)使用BX及寄存器相对寻址方式的段内间接寻址
解: (1)JMP D
偏移地址 = D + IP = 5119H + 2BC0H = 7CD9H
(2)JMP BX
(16d×(DS)+(BX))= 212A0 + 1200 =(224A0)= 0600H
(3)JMP [ BX+D]
(16d ×(DS)+(BX)+D)= 212A0 + 1200 + 5119 = 275B9 = 098AH
2. 条件转移指令 不影响标志
有符号数间的次序关系称为:大于(G)、等于(E)、小于(L);
无符号数间的次序关系称为:高于(A)、等于(E)、低于(B)。
无符号数和有符号数,两数是否相等可由ZF标志的反映。
进位标志CF反映两个无符号比较后的大小关系。
两个有符号数比较后的大小关系,由符号标志SF和溢出标志OF一起来反映。
例1:下面的程序测试AX的低四位是否全是0,如果均是0,那么使CX=0,否则使CX=-1
MOV CX,-1 ;先使CX=-1
TEST AX,0FH ;测试AX的低4位
JNZ NZERO ;不全为0则转移
MOV CX,0 ;全为0时使CX=0
NZERO:……
例2:设要比较的两个不相等的有符号数a和b,分别存放在寄存器AX和BX中,
执行指令“CMP AX,BX”后,标志SF及OF的设置情况和两数的大小情况如下:
当没有溢出(OF=0)时,若SF=0,则a>b;若SF=1,则a<b
当产生溢出(OF=1)时,若SF=0,则a<b;若SF=1,则a>b
习题1:设X、Y均为存放在X和Y单元中的16位操作数,先判X >50否,如满足条件则转移到
TOO—HIGH去执行,然后做X-Y,如溢出则转移到OVER去执行,否则计算|X-Y|,并把结果存入RESULT中。
MOV AX, X
MOV BX, 50
CMP AX, BX ;判断X > 50?
JG TOO—HIGH ;如果X > 50则跳转TOO—HIGH
SUB AX, BX ;X-Y
JO OVER ;如果溢出(OF=1)则跳转OVER
JNS NONEG ;X - Y 为正转移到NONE
NEG AX ;AX取补:0-AX
NONEG:MOV RESULT,AX
TOO—HIGH:……
OVER:……
习题2:假设有100个16位无符号数存放在从1234:5678H开始的内存中,现需要求它们的和。
设把32位的和保存在DX(高位)和AX寄存器中。
MOV AX,1234H ;不能直接将立即数传送到段寄存器
MOV DS,AX ;置数据段寄存器值
MOV SI,5678H ;置指针初值
MOV AX,0 ;清32位累加和
MOV DX,AX
MOV CX,100 ;置数据个数计数器
NEXT: ADD AX,[SI] ;求和
ADC DX,0 ;加上可能的进位
INC SI ;调整指针
INC SI
DEC CX ;计数器减1
JNZ NEXT ;如果不为0,那么就继续累加下一个数据
循环指令 不影响各标志位
(1)计数循环指令LOOP
格式: LOOP 标号
指令使寄存器CX的值减1,如果结果不等于0,则转移到标号,否则顺序执行;
该指令等同于如下的两条指令: DEC CX
JNZ 标号
通常在利用LOOP指令构成循环时,先要设置好计数器CX的初值,即循环次数。由于首先进行CX寄存器减1 操作,再判结果是否为0,所以最多可循环65536次。
例:如下程序片段实现把从偏移1000H开始的512个字节的数据复制到从偏移3000H开 始的缓冲区中(假设在当前数据段中进行移动)
MOV S1,1000H ;置源指针
MOV DI,3000H ;置目标指针
MOV CX,512 ;置计数初值
NEXT: MOV AL,[ SI ]
INC SI
MOV [ DI ],AL
INC DI
LOOP NEXT ;控制循环
(2)等于/全零循环指令LOOPE/LOOPZ
格式:LOOPE 标号 ;等于 / LOOPZ 标号 ;全零
指令使寄存器CX的值减1,当为0或相等时(且ZF=1),那么则转移到标号,否则顺序执行。
例:字符串中查找第一个非‘A’字符。设字符串长度已保存在CX中,并且DS:DI 指向字符串。如果找到,那么使BX指向该非‘A’字符,如果找不到,那么使BX=0FFFFH。
MOV AL,‘A’
DEC DI
NEXT: INC DI
CMP AL,[DI]
LOOPE NEXT
MOV BX,DI
JNE OK
MOV BX,-1
OK: ……
(3)不等于/非零循环LOOPNE/LOOPNZ
格式:LOOPNE 标号 ;不等于 / LOOPNZ 标号 ;非零
指令使寄存器CX的值减1,如果结果不为0不相等时,并且零标志ZF等于0,那么则转移到标号,否则顺序执行。(CX -1 != 0 且 ZF = 0)
(4)跳转指令JCXZ
格式: JCXZ 标号 ;CX = 0 则跳转标号,否则顺序执行
通常该指令用在循环开始前,以便在循环次数为0时,跳过循环体。
例如: ……
JCXZ OK ;如果循环计数为0,就跳过循环
NEXT: …… ;循环体
……
LOOP NEXT ;根据计数控制循环
OK: ……
习题1:有一串L字符的字符串存储于首地址为TABLE 的存储器中。如要求在字符串中查找“空格”字符,找到则继续执行,如未找到则转到NOT-FOUND去执行,编制此程序。
MOV CX, L ;将字符串长度L传送给CX
MOV SI,-1 ;使SI = -1,后面比较时将从0 开始比较
MOV AL,20H ;AL表示空格,20H是空格的ASCII码,可写成AL, ' '
NEXT: INC SI ;SI加一 ,第一次为0
CMP AL,TABLE [ SI ]
LOOPNE NEXT ;CX!=0或CMP不相等则继续NEXT循环
JNZ NOT-FOUND ;CX = 0,跳转NOT-FOUND
……
NOT-FOUND:
……
习题2:若自BLOCK开始的内存缓冲区中有100个字节带符号数,要找出其中最大值,把它存放到MAX单元中。
MOV BX,OFFSET BLOCK ;把BLOCK偏移地址送给BX
MOV AX,[BX] ;取出来第一个数送给AX
INC BX ;BX = BX+1
MOV CX,99 ;
AGAIN:CMP AX,[BX] ;BX 与BX+1相比较
JG NEXT ;AX大于
MOV AX,[BX] ;
NEXT : INC BX
LOOP AGAIN
MOV MAX,AX
习题3:已知存储器中有一个首地址为ARRAY的100个字数组,现要求把数组中的每个数加1(不考虑溢出的可能性),试编制完成此功能的程序段。
MOV CX,100 ;100个字数组,循环100次
LEA BX,ARRAY ;MOV BX,OFFSET ARRAY同理
INCR: INC [BX] ;BX内容+1
ADD BX,2 ;BX指针+2
LOOP INCR
第六章:掌握字符串操作、BCD码的加减法指令
组合BCD码的算术运算调整指令
1、组合的BCD码加法调整指令DAA(Decimal Adjust for Addition)
格式:DAA;该指令必须在加法操作后执行
这条指令对在AL中的和(由两个组合的BCD码相加后的结果)进行调整
调整方法如下:
(1)如AL中的低4位在A~F之间,或AF为1,则AL←(AL)+6,且使AF=1;
(2)如AL中的高4位在A~F之间,或CF为1,则AL←(AL)+60H,且使CF=1。
该指令影响标志AF,CF,PF,SF和ZF,但不影响标志OF。
例1:
MOV AL,34H
ADD AL,47H ;AL = 34H + 47H = 7BH,AF=0,CF=0
DAA ;AL = 7BH + 06H = 81H,AF=1,CF=0
ADC AL,87H ;AL = 81H + 87H = 08H,AF=0,CF=1
DAA ;AL = 08H + 60H = 68H,AF=0,CF=1
ADC AL,79H ;AL = 68H + 79H = 0E1H,AF=1,CF=0
DAA ;AL = 0E1H + 60H + 06H = 47H,AF=1,CF=1
例2: (BCD3)←(BCD1)+(BCD2)
设(BCD1)=34H,(BCD+1)=18H,(BCD2)=89H,(BCD2+1)=27H。指令如下:
MOV AL,BCD1 ;AL = 34H
ADD AL,BCD2 ;AL = 34H + 89H = 0BDH,AF=0,CF=0
DAA ;AL = 0BDH + 60H + 06H = 23H,AF=1,CF=1
MOV BCD3,AL ;(BCD3) = 23H
MOV AL,BCD1+1 ;AL = 18H
ADC AL,BCD2+1 ;AL = 18H + 27H = 3FH,AF=0,CF=0
DAA ;AL = 3FH + 06H = 46H,AF=1,CF=0
MOV BCD3+1,AL ;(BCD3+1) = 46H
∴ (BCD3)= 4623H AL=46H,CF=0,AF=1
2、组合的BCD码减法调整指令DAS
格式:DAS;该指令必须在减法操作后执行
这条指令对在AL中的差(由两个组合的BCD码相减后的结果)进行调整,产生一个组合的BCD码
调整方法如下:
(1)如AL中的低4位在A~F之间,或AF为1,则AL←(AL)- 6,且使AF=1;
(2)如AL中的高4位在A~F之间,或CF为1,则AL←(AL)- 60H,且使CF=1。
该指令影响标志AF,CF,PF,SF和ZF,但不影响标志OF。
例1:
MOV AL,45H ;AL = 45H
SUB AL,27H ;AL= 45H - 27H = 1EH,AF=1,CF=0
DAS ;AL = 1EH - 06H = 18H,AF=1,CF=0
SBB AL,49H ;AL = 18H - 49H = 18H + B7H = 0CFH,AF=1,CF=1
DAS ;AL= 0CF - 60H - 06H = 69H,AF=1,CF=1
例2;(BCD1)=1234,(BCD2)=4612,试写出指令完成(BCD3)←(BCD1)-(BCD2)
MOV AL,BCD1 ;AL = 34H
SUB AL,BCD2 ;AL = 34H - 12H = 22H,CF=0,AF=0
DAS ;AL = 22H
MOV BCD3,AL ;(BCD3) = 22H
MOV AL,BCD1+1 ;AL = 12H
SBB AL,BCD2+1 ;AL = 12H - 46H = 12H + 0BAH = 0CCH,CF=0,AF=0
DAS ;AL = 0CCH - 60H - 06H = 66H,CF=1,AF=1
MOV BCD3+1,AL ;(BCD3+1) = 66H
∴ (BCD3)= 6622H,CF=1,AF=1
未组合BCD码的算术运算调整指令
1、未组合的BCD码加法调整指令AAA
格式:AAA;该指令必须在加法操作后执行
这条指令对在AL中的和(由两个未组合的BCD码相加后的结果)进行调整,产生一个未组合
的BCD码。调整方法如下:
( 1) 如AL中的低4位在0~9之间,且AF为0,则转(3);
( 2) 如AL中的低4位在A~F之间,或AF为1,则AL = (AL) + 6,AH = (AH) + 1,且AF位置1
( 3 ) 清除AL的高4位;
( 4 ) AF位的值送CF位。
该指令影响标志AF和CF,对其他标志均无定义。
例1:
MOV AX,7 ;AX = 0007H
ADD AL,6 ;AL = 07H+ 06H = 0DH,AF=0,CF=0
AAA ;AL = 0DH+ 06H = 13H,AL=03H,AH = 01H,AF=1,CF=1
ADC AL,5 ;AL = 03H + 05H + CF = 09H,AH=01H,AF=0,CF=0
AAA ;AL = 09H,AH=01H,AF=0,CF=0
ADD AL,39H ;AL = 09H + 39H = 42H,AH=01H,AF=1,CF=0
AAA ;AL = 42H + 06H = 48H,AL = 08H,AH=02H,AF=1,CF=1
2、未组合的BCD码减法调整指令的ASS
格式:AAS;该指令必须在减法操作后执行
这条指令对在AL中的差(由两个未组合的BCD码相减后的结果)进行调整,产生一个未组合
的BCD码。调整方法如下:
(1) 如AL中的低4位在0~9之间,且AF为0,则转(3)
(2) 如AL中的低4位在A~F之间,或AF为1,则AL←(AL)- 6,AH←(AH)- 1,且AF位置1;
(3) 清除AL的高4位
(4) AF位的值送CF位。
该指令影响标志AF和CF,对其他标志均无定义。
例1:
MOV AL,34H ;AL = 34H
SUB AL,09H ;AL = 34H + 09H = 2BH,AF=1,CF=0
AAS ;AL = 2BH - 06H = 25H,AL = 05H,AF=1,CF=1
3、未组合的BCD码乘法调整指令AAM
格式:AAM;该指令必须在乘法操作后执行
这条指令对在AL中的积(由两个组合的BCD码相乘的结果)进行调整,产生两个未组合的BCD码 。调整方法如下:
(1)AL = AL % 10 (余)
(2)AH = AL / 10 (商)
该指令影响标志SF,ZF和PF,对其他标志无影响。
例:
MOV AL,03H ;AL = 03H
MOV BL,04H ;AL = 04H
MUL BL ;AL = 03H × 04H = 0CH,AH=00H
AAM ;AL = 0CH % 10H = 02H,AH = 0CH / 10H = 01H
4、未组合的BCD码除法调整指令AAD
格式:AAD;该指令前必须在除法操作前执行
这条指令把存放在寄存器AH(高位十进制数)及存放在寄存器AL中的两位非组合BCD码,
调整为一个二进制数,存放在寄存器AL中。调整的方法如下:
(1)AL = AH × 10 + (AL)
(2)AH = 0
该指令影响标志SF,ZF和PF,对其他标志无影响 。
例:
MOV AH, 04H ;AH = 04H
MOV AL, 03H ;AL = 03H
MOV BL, 08H ;BL = 08H
AAD ;AL= 04H × 10 + 03H = 43D = 2BH , AH=00H
DIV BL ;AL= 2BH / 08H = 05H , AH = 2BH % 08H = 03H