汇编语言复习提纲

99封情书 提交于 2019-12-05 00:07:09

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

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

 

 

 

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!