汇编语言复习提纲

第一章:掌握各进制的转换,有符号数的补码表示

1.1 各进制的转换

 

 

 

 

 十进制数一般用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位数据。 

 

 

 

标志寄存器

 

 

(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

如图所示:                                              

 

 

                        

③ 指令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

 

 

 

 

 

 

 

 

posted @ 2019-11-19 16:22  ✿Trepverter╮  阅读(1510)  评论(0)    收藏  举报