您好,欢迎来电子发烧友网! ,新用户?[免费注册]

当前位置:电子发烧友网 > 图书频道 > 电子 > 《微计算机原理》 > 第3章 8086指令系统

第3节 逻辑运算、移位、循环指令

 

  § 3.3.4 逻辑运算、移位、循环指令

  1、 逻辑运算指令

  逻辑运算有"与(AND)"、"或(OR)"、"非(NOT)"、"异或(XOR)"、"测试(TEST)"。

       (1) 逻辑"与"AND

  AND dst ,src

  功能:dst←dst ∧ src,目的操作数dst与源操作数src对应位相"与",结果放在dst中。

  (2) 逻辑"或"指令

  OR dst ,src

  功能:dst←dst ∨ src,目的操作数dst与源操作数src对应位相"或",结果放在dst中。

  (3) 逻辑"异或"指令

  XOR dst ,src

  功能:dst←dst ⊕ src,目的操作数dst与源操作数src对应位相"异或",结果放在dst中。(异或:不同的数异或为1;相同的数异或为0)。

  (4) 逻辑"非"指令

  NOT dst

  功能:dst←,目的操作数dst每一位取反后,放在dst中。

  (5)"测试"指令

  TEST dst,src

  功能:测试dst中某些位是否为1,当要测试dst中某些位时,在src中对应位置1。该指令使用"与"运算进行测试,但"与"运算的结果不送给dst,而只反映在标志ZF中。当对应位为1时,ZF=1;当对应位为0时,ZF=0。

  2、 移位指令

  移位操作如图3-17所示。

  SAL,SHL,SAR,SHR指令的格式相同,以SAL为例:

  SAL DX,1 ; DX的值左移一位,最低位补0

  SAL AX,CL ;AX的值左移CL位,最低位补0,

  ;CL=0,1,2,....,255

  算术移位(SAL、SAR)把操作数看成有符号数。SAR指令在移位过程中保持符号位不变。SAL指令不保持符号位,但当符号位发生变化时(最高位与CF不同),用 OF标志置1表示出来。

  逻辑左移SHL把操作数看成无符号数。

  将一操作数左移一位,相当于将其乘2。将一操作数右移一位,相当于将其除以2。因此,可以用移位操作代替部分乘除操作,只要不产生溢出,这种代替是正确的。(用CF标志判别无符号数运算是否溢出,CF=1,表示溢出。用 OF标志判别有符号数运算是否溢出,OF=1,表示溢出)。

  操作数B7H(1011 0111B)连续左移时的变化

  操作数B7H(1011 0111B)连续右移时的变化

  3、 循环指令

  循环操作如图3-18所示。

  ROL,RCL,ROR,RCR指令的格式相同,以ROL为例:

  ROL BX,1 ; BX的值循环左移一位

  ROL WORD PTR [DI],CL ;内存单元的值循环左移CL位 ;CL=0,1,2,....,255

  §3.3.5 控制转移指令

  8086程序中的指令存放在内存中的一个或几个段中,这些段称为代码段,CPU执行的下一条指令的地址由CS(代码段基地址寄存器)和IP(指令指针)指定。CPU正在执行的指令所在的代码段称为"当前代码段",其基地址为CS的值。代码段的容量可达64K,IP的值为0000H~FFFFH。

  一般情况下,CPU按顺序执行指令,每执行一条指令,IP增加一个值(该值等于这条指令的长度,指指令的机器码长度),当IP到达一段的末尾时,改变CS的值并重新设定IP指向新段的开始。

  若CPU正在执行的指令为控制转移指令,CPU改变执行顺序,转移到另一处执行。此时,IP 和/或 CS的值发生改变。

  转移指令包括:

  子程序调用指令(CALL)和子程序返回指令(RET)。

  无条件转移指令(JMP)和条件转移指令(JZ,JNZ等)。

  重复(循环)控制指令(LOOP,LOOPNZ等)。

  中断指令(INT n)和中断返回指令(IRET)。

  如果转移指令只改变IP的值,不改变CS的值,即目标指令仍在当前代码段中,称为"段内转移"。

  如果转移指令改变IP和CS的值,即目标指令不在当前代码段中,而在另一代码段内,称为"段间转移"。(转移后的代码段成为新的当前代码段)。

  1、 无条件控制转移

  (1) JMP指令

  JMP 目标地址

  功能:无条件转移到目标地址。

  在程序设计中,目标地址通常用一个指令标号来表示。

  (2) 调用指令(CALL)和返回指令(RET)

  CALL 目标地址

  RET [n];n为0~FFFFH之间的一个偶数

  在大型程序中,有时,一段相同的程序多次被使用,可以把这段程序单独提出来编写,称为"子程序",需要该段程序时,用CALL指令调用子程序,这种编程处理方法,称为"子程序结构",如图19所示。

相对于子程序,调用程序称为主程序如图1所示。 CALL指令用在主程序中调用子程序,它使CPU转入子程序执行。RET用在子程序中控制CPU返回主程序,如图20所示。

  为了使CPU在执行完子程序后,能正确地返回CALL指令的下一条指令,CALL指令必须把"返回地址"存入堆栈。RET从堆栈中取

  出该返回地址,从而返回到主程序的正确位置。

  如果子程序P与主程序M在同一个代码段,称为段内调用,该子程序称为NEAR型子程序;如果子程序P与主程序M不在同一个代码段,称为段间调用,该子程序称为FAR型子程序。

  段间调用与返回时,CALL/RET指令的操作(如图21所示):

  CALL:

  ① SP减2,把返回地址的段值(CS)推入堆栈。

  ② SP减2,把返回地址的偏移量(IP)推入堆栈。 ①、②两步使RET正确返回。

  ③ 把子程序地址的偏移量送给IP,把子程序地址的段值送给CS。从而使CPU转入子程序运行。

  RET:

  ① 从堆栈中取出返回地址的偏移量送给IP,SP加2。

  ② 从堆栈中取出返回地址的段值送给CS,SP加2。 从而使CPU执行CALL指令后面的那条指令。

  段内调用与返回时,CALL/RET指令的操作:

  CALL:(如图22)

  ① SP减2,把返回地址的偏移量(IP)推入堆栈。以便RET正确返回。(不保存返回地址的段值)。

  ② 把子程序地址的偏移量送给IP。从而使CPU转入子程序运行。

  RET:从堆栈中取出返回地址的偏移量,送给IP,SP加2。

  从而使CPU执行CALL指令后面的那条指令。

  "RET n"(n为偶数)指令,除完成一般RET指令的动作外,还使SP加n。"RET n"用于有入口参数的子程序中,清除主程在执行CALL指令之前推入堆栈的入口参数。

  2、 条件控制转移指令

  条件控制转移指令,以一个或几个标志位作为条件,或以CX的值作为条件,当条件满足时,转移到目标地址,否则,执行下一条指令。

  条件转移指令的一般格式是:

  JX 短目标地址

  其中,X是表示条件的1~3个字母。"短目标地址"是指,JX指令与目标地址之间的距离范围为-128~+127。(区别:无条件转移指令JMP可以跳转到任何位置)。

  条件转移指令的中,相当一部分指令的条件,是CMP、SUB等指令比较两个数后,在标志寄存器中设置的标志位。以CMP指令为例,无符号数和有符号数比较后,设置的标志位不同,如下表所示

  "CMP dst,src"指令执行后设置的标志

  条件转移指令使用大于(Greater)、小于(Less)来反应有符号数比较后设置的标志位。使用高于(Above)、低于(Below)来反应无符号数比较后设置的标志位,如下表所示。

  3、 重复控制指令(循环指令)

  重复控制指令属于条件转移指令,当条件满足时,转移到目标地址,从而使重复控制指令与目标地址之间的程序(称为循环体)被重复执行(循环)。

  (1) LOOP指令

  LOOP 短目标地址

  功能:使CX的值减1后,若CX≠0,转移到目标地址。

  注意,LOOP指令使CX减1时,不会引起标志位的变化。

  LOOP指令相当于以下两条指令:

  DEC CX

  JNZ 短目标地址   LOOP指令使循环体执行CX次如图3-23所示。

当CX被赋初值0时,循环体被执行65536次。

  (2) LOOPZ(或LOOPE)

  格式:LOOPZ 短目标地址

  功能:使CX减1后,当CX≠0且ZF=1时,转移到目标地址。

  LOOPZ/LOOPE指令使循环体最多执行CX次,在循环过程中,若不满足ZF=1,将提前结束循环。

  (3) LOOPNZ(或LOOPNE)

  格式:LOOPNZ 短目标地址

  功能:使CX减1后,当CX≠0且ZF=0时,转移到目标地址。

  LOOPNZ/LOOPNE指令使循环体最多执行CX次,在循环过程中,若不满足ZF=0,将提前结束循环。

  § 3.3.6 串操作指令

  (一) 串的概念

  在汇编语言程序设计中,"串"可以是任意一段连续的内存(1~N字节)。串中的每一个值可以是字符(字符串)或数据(数据串)。 串在内存中的地址以串的第一字节的地址表示,如,设字符串'ABCDEF'在内存中按如下存放,则称该串的地址为 0724H。

(二) 串操作的特点

  在汇编语言程序设计中,可对串进行如下操作:

  (S=STRING ,B=BYTE, W= WORD)

  串的传送 MOVS/MOVSB/MOVSW(MOVE)

  串的比较 CMPS/CMPSB/CMPSW(COMPARE)

  串的检索 SCAS/SCASB/SCASW(SCAN)

  存串 STOS/STOSB/STOSW(STORE)

  取串 LODS/LODSB/LODSW(LOAD)

  这些操作有如下特点:

  (1) 可对字节串(如MOVSB)或字串操作(如MOVSW)。

  (2) 源操作数(称为源串): 段地址DS,偏移量SI

  目的操作数(称为目的串):段地址ES,偏移量DI

  串操作指令是唯一的一组源操作数和目的操作数均在内存的指令。

  (3) 串操作指令执行时,每执行一次,自动修改源串和目的串的地址偏移量SI和DI。SI和DI的修改方式与标志寄存器的方向标志

 

  DF有关:STD指令:置DF=1 (Set DF)

  CLD指令:置DF=0 (Clear DF)

  (4) 串操作指令可以加重复前缀。

  1、 字符串的传送指令

  把源字符串中DS:SI处的元素(字节或字)复制到目的字符串中ES:DI处,且自动修改SI、DI。

  MOVS 目的字串,源字串 ;每次复制一字。

  MOVSW ;每次复制一字

  MOVSB ;每次复制一字节。

  执行字符串的传送指令,有以下五个步骤:

  (1) 用CLD指令使DF=0或用STD指令使DF=1,以指顶字符串的传送指令执行后,SI、DI是增加(DF=0)或减少(DF=1)。

  (2) 源字符串的地址送DS、SI。

  (3) 目的字符串的地址送ES、DI。(当源字符串和目的字符串在同一数据段时,ES=DS,且一般在程序的起始处设置)。

  (4) 将字节或字数送入CX。

  (5) 执行字符串传送指令。

  字符串传送中,DF标志位的影响。

  DF标志位影响字符串指令执行后SI、DI是增加(DF=0)或减少(DF=1),如图3-24所示。

  2、 字符串的比较指令

  两个字符串对应位置的元素(字节或字)进行比较(DS:SI处元素与ES:DI处元素比较),比较结果反应在标志寄存器的标志位。且自动修改SI、DI。

  CMPS 目的字串,源字串;DS:SI处与ES:DI处比较一字。

  CMPSW ;DS:SI处与ES:DI处比较一字。

  CMPSB ;DS:SI处与ES:DI处比较一字节。

  CMPSxx指令使用"源串中DS:SI处元素-目的串ES:DI处元素"的算法进行比较。(区分:"CMP dst,src"指令使用"dst-src"的算法进行比较)。

  3、 字符串的扫描指令

  AL或AX与目的字符串中ES:DI处的元素(字节或字)进行比较,比较结果反应在标志寄存器的标志位。且自动修改DI。(该指令不使用SI,因此,该指令执行时SI不变)。即,查找(称为扫描)字符串中是否含有与AL/AX相同的元素。

  SCAS 目的字串 ;AX与ES:DI处比较。

  SCASW ;AX与ES:DI处比较。

  SCASB ;AL与ES:DI处比较。

  SCASxx指令使用"AL/AX-目的串中ES:DI处元素"的算法进行比较。

  4、 字符串的装入指令

  把源字符串中DS:SI处的元素(字节或字)装入AL或AX中。且自动修改SI。(该指令不使用DI,因此,该指令执行时DI不变)。LODS 源字串 ;DS:SI处的元素(字)→AX。

  LODSW ;DS:SI处的元素(字)→AX。

  LODSB ;DS:SI处的元素(字节)→AL。

  5、 字符串的存储指令

  把AL或AX中的值存入目的字符串中ES:DI处。且自动修改SI。(该指令不使用SI,因此,该指令执行时SI不变)。

  STOS 源字串 ;AX →ES:DI处。

  STOSW ;AX→ES:DI处。

  STOSB ; AL→ES:DI处。