复习点
这章的东西也太多了吧!
一、指令和指令系统
1.指令
指令是计算机执行某种操作的命令,是程序员指挥计算机工作的最小单位。
a.指令格式
指令格式是指表示一条指令的二进制代码形式,由操作码和地址码两部分组成,包含了操作码(规定了指令操作的性质和功能)、操作数或操作数存放地址、操作结果存放地址和下一条指令执行地址等基本信息。
- 指令字长:二进制代码的位数。一般指令字长是机器字长的整数倍。
- 机器字长:计算机进行一次整数运算所能处理的二进制数据的位数。
- 单字长指令:指令字长等于机器字长的指令。
b.指令的操作码
(1)定长操作码:长度固定。优点是硬件设计简单、指令译码速度快;缺点是操作码平均长度长,需要的指令字长也长。
(2)可变长操作码:也叫扩展操作码,操作码的长度位数可变。优点是操作码的平均长度相对较短,可通过增加操作码的长度新增指令;缺点是控制器设计复杂,指令的译码时间较长。
c.指令的地址码
根据地址码所给出的地址的个数,将指令分类。
(1)零地址指令:这类指令中只有操作码而无操作数
- 一种情况是不需要操作数,比如空操作指令、停机指令等。
- 另一种情况是隐含了操作数,比如字符串处理指令,源操作数和目的操作数分别隐含在源变址寄存器SI和目的变址寄存器DI所指定的存储单元中。
(2)一地址指令:这类指令中只给出一个地址
- 一种情况是这个地址既是操作数的地址,又是操作结果的储存地址。比如加1、减1这些指令。
- 另一种情况是地址码指定了源操作数的地址,目的操作数和操作结果的地址隐含给出。比如80X86CPU的乘法和除法指令。
(3)二地址指令:这类指令在指令中给出两个操作数地址,是常用的指令格式。
- 这类指令的操作结果一般都放在目标操作数所指定的地址中。
- 80X86CPU的加法、减法、与运算、或运算都属于二地址指令。
(4)三地址指令:这类指令会给出两个操作数地址和一个结果地址。
- 显而易见,这类指令操作后操作数不变,操作结果存入结果地址中。
- 但是这类指令指令码较长,占用空间且相对费时间,所以一般用在字长较长的大型计算机中。
(5)多地址指令:给出三个以上的操作数地址
- 指令码长,仅用在某些性能较好的大型机中,如CDC STAR-100计算机的向量和矩阵运算指令。
2.指令系统
- 计算机全部指令的集合称为指令系统。
- 指令系统是计算机软件和硬件的界面,反映了计算机硬件能够完成的功能,也是系统软件设计的基础。
- 指令系统的设计包括指令格式、指令类型、寻址方式和数据形式。
- CPU类型不同,指令系统不同,功能也不同。
二、80X86的寻址方式
1.指令寻址
- 寻找下一条将要执行的指令所在的存储器地址。
(1)顺序寻址
一条指令执行结束们根据指令指针寄存器的内容访问存储器,开始执行下一条指令。
(2)跳转寻址
有程序分支时,需要控制流程跳转到指定指令位置。根据获得目标地址的方法不同,分为以下两种:
a.相对寻址(较为常用)
- 指的是指令代码提供的目标地址是相对于当前指令地址的位移量。
- 目标地址 = 当前指令地址 + 位移量
- 简单解释:当同一程序被安排到不同的存储区域执行时,指令间的位移并没有改变,所以采用这种方式就不需要改变转移地址。
b.直接寻址和间接寻址
- 直接寻址:指令代码直接提供目标地址
- 间接寻址:指令代码指出寄存器或存储单元地址,目标地址来自寄存器(目标地址的寄存器间接寻址)或存储单元(目标地址的存储器间接寻址)
2.数据寻址
- 在这些方法中,除立即数寻址和寄存器寻址以外,其余的寻址都属于存储器寻址,即操作数都存放在存储器单元中(I/O等指令特殊)
a.立即数寻址
- 概念:在这种寻址方式中,操作数紧跟在操作码之后作为指令机器代码的一部分。
- 注意:指令中有两个操作数时,左面的为目的操作数,右面的为源操作数。该方式只适用于源操作数。
- 优点:立即数寻址简单,速度快。
- 缺点:不够灵活,修改数据就需要修改程序,所以常用来设置常数。
- 举例:MOV AX,1234H,将数据1234H放入AX中。
b.寄存器寻址
- 概念:指令的操作数存放在寄存器中,可以直接使用寄存器的名字表示它保存的数据。
- 注意:绝大多数指令采用通用寄存器寻址,部分指令支持专用寄存器。
- 优点:无需访问存储器,简单快捷,指令字长短。
- 举例:MOV EBX EAX,将EAX中的内容传送给EBX。
c.存储器直接寻址
- 概念:若操作数在主存单元中,在指令代码中直接给出操作数的有效地址的方式。
- 按照80X86CPU访问存储器的方式,指令中给出的地址是操作数在数据段中的偏移地址,段地址和偏移地址相结合才能得到操作数在主存中的实际地址。
- 常用于存取变量。
- 举例:MOV AL,[2000H] 操作数的物理地址为:40000H+2000H=42000H
- 此外还有一种有效地址EA以变量名的方式给出的方式:
COUNT EQU 100H (EQU是一个伪指令,第六章会提到)
MOV CX , COUNT
!注意:不管数据在哪个段内存放,只要不是DS,一定要加段超越前缀!比如该数据传输指令:MOV AX , ES:[2000H]
d.寄存器间接寻址
- 概念:操作数的有效地址存放在寄存器中。
- 举例:MOV AX,[BX],将40100单元的内容送给AX。
e.寄存器相对寻址
- 概念:有效地址是寄存器内容与位移量之和。
- 举例:MOV AL,[BX + 05],将62005H单元的内容9AH送AL
f.基址加变址寻址和相对基址加变址寻址
- 基址加变址寻址概念:操作数的有效地址是由基址寄存器(BX或BP )的内容加上变址寄存器(SI或DI)的内容构成。
- 当使用基址寄存器BX时,默认段寄存器是DS 。当使用基址寄存器BP时,默认段寄存器是SS 。
- 举例:MOV AX , [BX+SI] ,将52006H单元的内容送AX 。
- 相对基址加变址寻址概念:操作数的有效地址是由基址寄存器(BX或BP )的内容加上变址寄存器(SI或DI)的内容再加上位移量构成。
- 举例:MOV AH , [BX+DI+1234H] ,将41444H单元的内容送AH 。
g.带比例的变址寻址
- 概念:在32位的寻址方式中,支持变址寄存器内容乘以一个常数(可取1、2、4、8),这种寻址方式称为带比例的变址寻址。可以和前面的几种方式结合形成新的寻址方式。
三、80X86寻址方式的特点
- 源操作数写在右边,目的操作数写在左边。
- 源操作数可以是立即数或存放在寄存器、存储器中;但目的操作数只能是寄存器或存储器寻址。
- 两个操作数不能同时为存储器寻址方式。
四、80X86常用指令
- REG表示寄存器,IMM表示立即数,MEM表示存储器,SEG表示段寄存器后面不再赘述。
- 总的原则:两个操作数不能同时存储器寻址方式且目的操作数不能是立即数。
1.数据传送指令
该类指令除标志寄存器传送指令外,均不影响标志位。
(1)通用数据传送指令
a. 传送指令MOV
- 格式:MOV DEST,SRC。
- 功能:将数据由源位置传送至目的位置,源操作数不变。
- 影响的标志位:不影响标志位。
- 注意事项:
- 目的操作数和源操作数类型必须一致(意思就是“长度”或“位数”要相同)。
- 不允许在段寄存器之间直接传送数据。
- CS段寄存器不能作为目的操作数,因为改变CS的值会影响自动取指
IP也不能作为目的操作数。 - 源操作数不能是BX + SI
- SP不能用作间址寄存器
- 立即数不能直接传给段寄存器
b.交换指令XCHG
- 功能:将源操作数和目的操作数的内容互换。
- 影响的标志位:不影响标志位。
- 注意事项:src和dest的数据类型要一致;两个存储器操作数之间不能实现直接交换。
c.换码指令XLAT
- 格式一:XLAT LABEL(表示首地址)
- 格式二:XLAT 隐含了首地址在BX寄存器中。
- 功能:以上两个格式等价。实际上是构造了一个表TABLE用来查询,将BX指定缓冲区中由AL指定的位移处的数据取出,传送到AL。
- 举例:设表首的偏移地址为2000H,要查找表内第4号单元(从0号算起)的内容并送回AL,试编写实现该要求的程序段。
MOV BX , 2000H
MOV AL , 04H
XLAT
执行结果为:AL = 09H
(2)地址传送指令
就是将存储器操作数的有效地址(偏移地址)或逻辑地址传送至指定的寄存器。
a.有效地址传送指令LEA
- 格式: LEA R16 , MEM
- 功能:将存储器操作数的有效地址传送至指定的16位寄存器中。
- 影响的标志位:该指令不影响标志位。
- 举例:讲一个有效地址传送到BX中:
MOV BX,4000H
MOV SI,3CH
LEA BX,[BX+SI+OF62H],结果是BX = 1339EH。注意,这里BX得到的是主存单元的有效地址,而不是物理地址,也不是该单元的内容。
b.地址指针传送指令LDS和LES
- 格式:LDS R16 , MEM 和 LES R16 , MEM
- 功能:将内存中MEM指定的字送至R16,并将MEM的下一字送DS或ES寄存器(LDS对应DS,LES对应ES)不影响标志位。
- 举例:(WORD PTR的意思是指定了立即数的类型为字)
MOV WORD PTR [3060H],0100H
MOV WORD PTR [3062H],1450H
LDS SI,[3060H]
最后的结果:DS = 1450H,SI = 0100H
2.堆栈操作指令
堆栈是一个“先进后出”的主存区域,位于堆栈段中。只有栈顶(地址较小的一端)一个出口。堆栈指令不影响标志位。
(1)进栈指令PUSH
- 格式:PUSH R16(16位寄存器)/M16(字存储单元)/SEG
- 功能:一是使堆栈指针SP减2;二是将源操作数(通用寄存器和段寄存器内容或存储器操作数)传送到当前栈顶,存放时低字节存放于低地址,高字节存放于高地址。
- 举例:将数据7812H通过寄存器压入堆栈
MOV AX,7812H
PUSH AX - 注意事项:程序中有一个PUSH,必有一个对应的POP;出栈指令的操作数不能为CS。
(2)出栈指令POP
- 格式:POP R16/M16/SEG
- 功能:一是使堆栈指针SP加2;二是将栈顶数据传送到目的操作数(通用寄存器、存储单元或段寄存器(CS除外))。还是一样,低对低,高对高。
- 举例:将栈顶一个字的内容弹出,送到AX寄存器。
POP AX
3.输入/输出指令
设备通过I/O端口和处理器交换信息。该指令不影响标志位。注意!只能利用AL/AX寄存器与I/O端口通信!
(1)输入指令IN
- 格式:IN AL/AX,数据
- 功能:将外设数据传送至CPU
- 举例:
IN AL,I8(这是字节输入,I8表示8位的端口号,将I/O端口I8的数据传送到AL中)
IN AX,I8(这是字输入,将I/O端口I8的数据传送到AL中,将I/O端口I8+1的数据传送到AH中)
IN AL,DX(这是字节输入,AL←I/O端口[DX],DX中存放着端口号)
IN AX,DX(这是字输入,AL←I/O端口[DX],AL←I/O端口[DX+1]) - 注意事项:前256个端口(即00H~FFH)可以直接寻址(立即数),大于256的端口号,用DX寄存器间接寻址;输入字节数据用的是AL,输入字数据用的是AX。
(2)输出指令OUT
- 格式:OUT 数据,AL/AX
- 功能:将CPU数据传送至外设
- 举例:(原理同输入指令一致)
OUT I8,AL
OUT I8,AX
OUT DX,AL
OUT DX,AX
4.算术运算指令
带符号不带符号、8位16位都可以运算。
(1)加法指令
a.不带进位加法指令ADD
- 格式:ADD REG,IMM/REG/MEM 或者是 MEM,IMM/REG
- 功能:将源操作数和摸底操作数相加,结果送到目的操作数。
- 影响的标志位:CF、AF、PF、SF、OF和ZF (就是6个条件码标志)
- 举例:
MOV AL,0FBH
ADD AL,07H
结果为102H,标志位的变化:OF=0,SF=0,ZF=0,AF=1,PF=0,CF=1 - 注意事项:段寄存器不参与运算
b.带进位加法指令ADC
- 格式:ADC REG,IMM/REG/MEM 或者是 ADC MEM,IMM/REG
- 功能:该指令将源操作数与目的操作数相加再与进位CF相加,结果送到目的操作数。
- 影响的标志位:CF、AF、PF、SF、OF和ZF 。
- 举例:
MOV AX,4652H 运行完后 AX = 4652H
ADD AX,0F0F0H 运行完后 AX = 3742H,CF = 1
MOV DX,0234H 运行完后 DX = 0234H
ADC DX,0F0F0H 运行完后 DX = F325H,CF = 0
该程序段完成的是02344652H + 0F0F0F0F0H = F3253742H的运算
由此可以得到结论:ADC指令和ADD指令结合可完成多字节数相加。
c.增量指令INC
- 格式:INC REG/MEM
- 功能:这是一个单操作数指令,将目的操作数的内容加1,并将结果回送到目的操作数。
- 影响的标志位:AF、PF、SF、OF和ZF(5个)
- 举例:
INC BX
INC WORD PTR[BX]
INC BYTE PTR[BX]
(2)减法指令
a.不带借位减法指令SUB
- 格式:SUB REG,IMM/REG/MEM 或者是 MEM,IMM/REG
- 功能:将目的操作数与源操作数相减,结果送到目的操作数。
- 影响的标志位:CF、AF、PF、SF、OF和ZF
- 举例:
MOV AL,0FBH
SUB AL,07H
操作结果为AL = 0F4H,CF = 0
b.带借位减法指令SBB
- 格式:SBB REG,IMM/REG/MEM 或者是 SBB MEM,IMM/REG
- 功能:将目的操作数与源操作数相减再与借位CF相减,结果送到目的操作数。
- 影响的标志位:CF、AF、PF、SF、OF和ZF
- 举例:
MOV AX,4652H 运行完后 AX = 4652H
SUB AX,0F0F0H 运行完后 AX = 5562H,CF = 1
MOV DX,0234H 运行完后 DX = 0234H
SBB DX,0F0F0H 运行完后 DX = 1143H,CF = 1
该程序完成的是02344562H - 0F0F0F0F0H = 11435562H的运算。
由此可以得到结论:SBB指令和SUB指令结合可完成多倍字长数相减。
c.减量指令DEC
- 格式:DEC REG/MEM
- 功能:单操作数指令,将目的操作数的内容减1,并将结果回送到目的操作数。
- 影响的标志位:AF、PF、SF、OF和ZF(5个)
- 举例:
DEC CX
DEC WORD PTR[SI]
d.求补指令NEG
- 格式:NEG REG/MEM
- 功能:将目的操作数求补运算,将其结果送回目的操作数。(实际上是用零减去操作数,然后将结果返回操作数)
- 影响的标志位:CF、AF、PF、SF、OF和ZF
- 举例:
MOV AX,0FF64H
NEG AX
结果为AX = 009CH
e.比较指令CMP
- 格式:CMP REG,IMM/REG/MEM 或者是 CMP MEM,IMM/REG
- 功能:将目的操作数减去源操作数,结果不回送。(所以通常用来比较大小,后面常跟条件转移指令,根据比较结果决定分支走向。)
- 影响的标志位:CF、AF、PF、SF、OF和ZF 。
- 举例:比较AL是否大于100(JB是一个跳转指令,无符号小于则跳转)
CMP AL,100
JB BELOW AL < 100,跳转到BELOW执行
SUB AL,100 AL >= 100,AL ← AL-100
INC AH
BELOW : ……
补充:标志位在比较大小中的使用:- 用ZF来判断两数是否相等。将两数相减即可
- 用CF判断两个无符号数的大小,两数相减看CF的值
- 通过OF和SF的变化来判断两个有符号数的大小。 OF=SF,则目的操作数大; OF≠SF,则目的操作数小。
(3)乘法指令
乘法指令都是:
- 被乘数隐含在AL(字节运算)或AX(字运算)中,运算结果保存在AX(字节运算)或AX和DX(字运算)中。
a.无符号数乘法指令MUL
- 格式:MUL R8/M8 或者是 MUL R16/M16
- 功能:实现两个无符号数的乘法运算。
- 影响的标志位:CF、OF,对其余的标志位不是没有影响,而是不可预测
- 举例:完成无符号数0B4H和10H的相乘
MOV AL,0B4H 真值为180
MOV BL,10H 真值为16
MUL BL
操作结果为AX = 0B40H,真值为2880.标志位CF = OF = 1 - 注意事项:
- 无符号乘法指令将操作数视为正整数做乘法,积也是正整数。
- 如果结果的高半部分(字节操作的AH或字操作的DX)不为零,表明其内容是结果的有效位,则CF=1、OF=1,否则CF=0、OF=0。
b.有符号乘法指令IMUL
- 格式:IMUL R8/M8 或者是 IMUL R16/M16
- 功能:完成两个有符号数的乘法运算。
- 影响的标志位:CF、OF,对其余的标志位不是没有影响,而是不可预测。
- 举例:完成有符号数0B4H和10H的相乘
MOV AL,0B4H 真值为-76
MOV BL,10H 真值为16
MUL BL AX = 0FB40H,真值为-1216,OF = CF = 1 - 注意事项:
- 有符号乘法指令视操作数为补码表示的有符号整数。
(4)除法指令
对于除法指令:
- DIV和IDIV对标志位的影响没有定义,但是可能产生溢出。
- 目的操作数隐含在AX和DX中。
- 对于字节除法:AX是被除数。完成运算后8位的商放入AL,8位的余数放入AH。
- 对于字除法:AX放被除数低位,DX放被除数高位。完成运算后16位的商放入AX,16位的余数放入DX。
- 发生溢出时会产生编号为0的内部中断。
a.无符号二进制除法DIV
- 格式:DIV R8/M8 或者是 DIV R16/M16
- 功能:完成两个无符号数的除法。
- 举例:无符号数0400H除以0B4H
MOV AX,0400H 操作后AX = 400H = 1024
MOV BL,0B4H 操作后BL = B4H = 180
DIV BL 操作后商AL = 05H,余数AH = 7CH = 124 - 注意事项:
- 无符号除法指令将操作数视为正整数做除法,商和余数也是正整数。
- 除数为0,或者在字节除时商超过8位,或者在字除时商超过16位,则发生除法溢出。
b.有符号二进制数除法指令IDIV
- 格式:IDIV R8/M8 或者是 IDIV R16/M16
- 功能:完成两个有符号数的除法。
- 举例:
MOV AX,0400H 真值为1024
MOV BL,0B4H 真值为-76
IDIV BL 商为F3H,真值为-13,余数为24H = 36 - 注意事项:
- 有符号除法指令将操作数视为补码表示的有符号整数,按补码除法规则进行,商河余数也是补码表示的有符号整数。
- 除数为0,或者在字节除时商不在-128 ~ 127范围内,或者在字除时商不在-32768 ~ 32767范围内,会发生除法溢出。
(5)符号扩展指令
对于符号扩展指令:
- 符号扩展指令不改变数据大小,只是加长了倍数。
- CBW和CWD都不影响标志位。
- 扩展位用原来的符号位填充。
a.字节扩展成字指令CBW
- 格式:CBW
- 功能: 将AL的最高有效位D7扩展至AH ,AL不变。
- 举例:
MOV AL,80H
CBW
最后结果 AX = 1111,1111,1000,0000 = FF80H
b.字扩展成双字指令CWD
- 格式:CWD
- 功能:将AX的符号位扩展到DX。
5.逻辑运算指令
除逻辑非指令外,逻辑运算指令均设置CF = OF = 0,根据结果设置SF、ZF、PF状态,对于AF未定义。
(1)逻辑与指令AND
- 格式:AND DEST,SRC
- 功能:对两个操作数执行按位的逻辑与运算(即两位都是1时,结果才是1,否则为0)。结果送到目的操作数。
- 举例:
MOV AL,25H
AND AL,31H
结果为AL = 21H,CF = OF = 0,SF = 0,ZF = 0,PF = 1 - 注意:AND指令可以用来复位一些位但不影响其他位。
(2)逻辑或指令OR
- 格式:OR DEST,SRC
- 功能:对两个操作数执行按位的逻辑或运算(即只要有一位是1,结果就是1,否则为0)。结果送到目的操作数。
- 举例:
MOV AL,45H
OR AL,31H
运算结果为:AL = 75H,CF = OF = 0,SF = 0,ZF = 0,PF = 0 - 注意:OR指令可以置位某些位但不影响其他位。
(3)逻辑异或指令XOR
-
格式:XOR DEST,SRC
-
功能:对两个操作数执行按位的逻辑异或运算(即相异或的两位不相同时,结果为1,相同时结果为0)。结果送到目的操作数。
-
举例:
MOV AL,45H
XOR AL,31H
运算结果为:AL = 74H,CF = OF = 0,SF = 0,ZF = 0,PF = 1 -
注意:XOR指令可以求反某些位但不影响其他位。
(4)逻辑非指令NOT
- 格式:NOT REG/MEM
- 功能:对操作数按位取反。单操作指令。
- 举例:
MOV AL,45H
NOT AL
运算结果为:AL = BAH - 注意事项:
- 逻辑非指令不影响标志位。
- 逻辑非指令的操作数可以是立即数以外的任意寻址方式。
(5)测试指令TEST
- 格式:TEST DEST,SRC
- 功能:对两个操作数执行按位的逻辑与运算,但它不保留运算结果。
- 举例:测试AL的D0位是否为0
TEST AL,01H
JNZ THERE ZF = 0,即D0 = 1,程序转移到THERE
…… ZF = 1,即D0 = 0,顺序执行
THERE: …… - 注意事项:
- TEST指令通常用来检测一些条件是否满足,但不改变源操作数。所以后面跟的一般都是条件转移指令。
6.移位运算指令
(1)非循环移位
对于逻辑移位和算术移位:
- 当源操作数为1时,表示移动一位,当移位位数大于1时,要移动的位数用CL寄存器表示。
- 对于溢出标志OF:当移动位数为1时才能判断,大于1时,OF是不确定的。且移动位数为1时,移位前和移位后的符号位不同OF = 1,否则OF = 0。
- 对于左移,最高位进入CF;对于右移,最低位进入CF。
a.逻辑移位
- 格式:
- 逻辑右移:SHR REG/MEM,1/CL
- 逻辑左移:SHL REG/MEM,1/CL
- 功能:进行逻辑左移/右移。
- 影响的标志位:除AF外都会影响(但是OF是个特例)
- 举例:
MOV AL,0F0H
SHL AL,1
SHR AL,1
第一步的结果为:AL = E0H,CF = 1,SF = 1,ZF = 0,PF = 0,OF = 0
第二步的结果为:AL = 70H,CF = 0,SF = 0,ZF = 0,PF = 0,OF = 1
注意事项: - 逻辑左移空出位补0,逻辑左移执行1位移位,相当于无符号数乘2。
- 逻辑右移空出位补0,逻辑右移执行1位移位,相当于无符号数除以2,商在目的操作数中,余数由CF反应。
b.算术移位
- 格式:
- 算数左移:SAL REG/MEM,1/CL
- 算数右移:SAR REG/MEM,1/CL
- 功能:进行算数左移/右移。
- 影响的标志位:除AF外都会影响(但是OF是个特例)
- 举例:
MOV CL,4
MOV AL,70H
SAR AL,1
SAR AL,CL
第一步的结果为:AL = 38H,CF = 0,SF = 0,ZF = 0,PF = 0,OF = 0
第二步结果为:AL = 03H,CF = 1,SF = 0,ZF = 0,PF = 1 - 注意事项:
- 算数左移空出位补0(在一定程度上等效于逻辑左移),算数左移执行1位移位,相当于有符号数乘2
- 算数右移空出位补符号位,算数右移执行1位,相当于有符号数除以2。但是有特殊情况:当操作数为负且最低位有1移出时,SAR指令的结果和IDIV的结果并不相同。
(2)循环移位指令
循环移位指令对操作数的规定以及对进位标志和溢出标志的影响和非循环移位指令一样,对其余标志不影响。
a.不带进位循环指令
- 格式:
循环左移:ROL REG/MEM,1/CL
循环右移:ROR REG/MEM,1/CL - 功能:进行不带进位的循环左移/右移
- 解释:这类指令将移出的位移到进位标志的同时移回到另一端形成循环。
b.带进位循环指令
- 格式:
循环左移:RCL REG/MEM,1/CL
循环右移:RCL REG/MEM,1/CL - 功能:进行带进位的循环左移/右移
- 解释:这类指令将进位标志视为数的最高位参加循环移位,即移出的位进入进位标志,进位标志则移到最高位(右移)或最低位(左移)。
7.程序控制指令
(1)无条件转移指令JMP
一些概念:
- 段内转移:目标地址在当前代码段内,目标属性为 NEAR。指令只修改IP。段内转移包括短转移(相对偏移量为1个字节,-128 ~ +127表达)和近转移(相对偏移量为1个字)
- 段间转移:目标地址在其他代码段内,目标属性为FAR。指令同时修改CS和IP。也叫远转移。
a.段内转移、相对寻址
JMP SHORT LABEL
JMP NEAR PTR LABEL
- 功能:程序转向的有效地址等于当前IP寄存器内容加上8位或16位位移量。若为8位,表示短转移,若为16位,表示近转移。
b.段内转移、间接寻址
JMP R16/M16
JMP BX
JMP WORD PTR[2000H]
- 功能:将一个16位寄存器或主存单元内容送入IP寄存器,作为新的指令指针,但不修改CS寄存器的内容。
c.段间转移、直接寻址
JMP FAR PTR LABEL1
- 功能:将标号所在段的段地址作为新的CS值,标号在该段内的偏移地址作为新的IP值。
d.段间转移、间接寻址
JMP FAR PTR MEM
- 功能:转移目标地址存放在主存中连续的两个字单元中,其中低位字送IP寄存器,高位字送CS寄存器。
(2)条件转移指令
- 功能:满足条件,则转移,不满足条件则顺序执行。
- 通用格式:Jcc label
- 对标志位的影响:该类指令对标志位均无影响。,但要利用标志。
- 注意事项:
- 注意:条件转移指令跳转的目标地址只能用用段内相对短跳转
- 利用标志判断的条件如下:
a.单标志位转移指令
b.无符号数的条件转移指令应用
- 无符号数的大小关系用低于(不高于等于)、不低于(高于等于)、低于等于、不低于等于……来形容。对应四条指令:JB(JNAE),JNB(JAE),JBE(JNA),JNBE(JA)。
- 两个有符号数的大小关系用小于、不小于、小于等于、不小于等于……来形容。对应四条指令:JL(JNGE)、JNL(JGE)、JLE(JNG)、JNLE(JG)
c.循环指令
- 以CX寄存器作为计数指针,每循环一次,CX减1,当CX减至0时,停止循环。
- 该指令不影响标志位。
- 无条件循环指令:JCXZ LABEL 和 LOOP LABEL
条件循环指令:LOOPZ/LOOPE LABEL 和 LOOPNZ/LOOPNE LABEL
d.子程序调用指令CALL
- near类型:调用指令与过程在同一个段中。
- far类型:调用指令与过程不在同一个段中
- 格式:CALL label、CALL R16/M16、CALL far ptr label、CALL far ptr mem
e.子程序返回指令RET
格式:
无参数段内返回:RET
有参数段内返回:RET I16
无参数段间返回:RET
有参数段间返回:RET I16
f.中断指令
8.其他指令
(1)串操作指令
这类指令的共同特点:
- SI:存放源操作数的偏移地址
- DI:存放目的操作数的偏移地址
- 源串隐含数据段,目的串隐含在附加数据段
- 每一次操作后,串指令自动修改地址指针
- 串传送、串存储、串读取指令不影响标志位;串比较、串扫描指令影响标志位。
a.串传送指令MOVS
- MOVSB ;字节串传送:ES:[DI]←DS:[SI], ;SI←SI±1,DI←DI±1
MOVSW ;字串传送:ES:[DI]←DS:[SI], ;SI←SI±2,DI←DI±2
b.串存储指令STOS
- STOSB ;字节串存储:ES:[DI]←AL,;DI←DI±1
STOSW ;字串存储:ES:[DI]←AX,; DI←DI±2
c.串读取指令LODS
- LODSB ;字节串读取:AL←DS:[SI], ;SI←SI±1
LODSW ;字串读取:AX←DS:[SI],;SI←SI±2
d.串比较指令CMPS
- CMPSB ;字节串比较: DS:[SI]- ES:[DI] , ; SI←SI±1,DI←DI±1
CMPSW ;字串比较: DS:[SI]- ES:[DI] , ; SI←SI±2,DI←DI±2
e.串扫描指令SCAS
- SCASB ;字节串扫描: AL- ES:[DI] ,; DI←DI±1
SCASW ;字串扫描: AX- ES:[DI] ,; DI←DI±2
f.重复前缀
- 任何串操作指令的前面都可以加重复前缀,以实现串操作的重复执行,重复次数隐含在CX寄存器中。
- 有以下三种
- REP:用在MOVS、STOS、LODS指令前。每次执行一次串指令,CX减1直到为0,重复执行结束。
- REPZ:用在CMPS、SCAS指令前,每执行一次串指令,CX减1,并判断ZF标志是否为0。当CX = 0或ZF = 0时,重复执行结束。
- REPNZ:用在CMPS、SCAS指令前,每执行一次串指令,CX减1,并判断ZF标志是否为1。当CX = 0或ZF = 1时。重复执行结束。
(2)处理机控制指令
a.空操作指令NOP
该指令不执行任何有意义的操作,空耗一个指令执行周期,常用于程序调试。(等效于XCHG AX,AX)
b.暂停指令HLT
该类指令使CPU进入暂停状态,这时CPU不进行任何操作。当CPU发生复位或来自外部的中断时,CPU脱离暂停状态。 要注意的是:该指令在计算机中将引起所谓的“死机”,一般不使用。
c.等待指令WAIT
该类指令在CPU的测试引脚为无效时(高电平),使CPU进入等待状态,这时,CPU并不做任何操作;测试引脚为有效时(低电平),CPU脱离等待状态,继续执行WAIT指令后面的指令。WAIT指令用于CPU和外部硬件同步。
d.段超越前缀
e.总线锁定前缀LOCK
- LOCK是一个指令前缀。
- 当CPU与其他处理机协同工作时,该指令可避免破坏有用信息。 CPU保持锁定
- 输出引脚LOCK有效,将总线锁定,使其他处理器不能控制总线。
(3)标志位传送指令
a.标志寄存器传送指令
- 格式:LAHF 和 SAHF
- 功能:
- LAHF是读标志寄存器,用于将FR的低字节(含SF、ZF、AF、PF和CF)读出后传送到AH寄存器。
- SAHF是写标志寄存器,将寄存器AH中的内容写入FR的低字节,取代某些标志位(SF、ZF、AF、PF和CF)的原来状态 。
- 影响的标志位:LAHF不影响标志位,SAHF影响标志位。
b.标志寄存器进出堆栈指令
这类指令在子程序调用或中断子程序中,常用此保护和恢复需要的标志位。
-
格式:PUSHF 和 POPF
-
功能:
-
PUSHF是标志寄存器入栈,将FR内容压入堆栈,同时修改堆栈指针。SP←SP-2 , SS:[SP]←FLAGS
-
POPF是标志寄存器出栈,将当前栈顶的一个字→ FR,同时修改堆栈指针。FLAGS←SS:[SP] , SP←SP+2
-
影响的标志位:PUSHF不影响标志位,POPF影响标志位
c.标志位操作指令
- 进位标志清零: CLC
- 进位标志置1: STC
- 进位标志取反: CMC
- 方向标志清零: CLD
- 方向标志置1: STD
- 禁止可屏蔽中断: CLI
- 允许可屏蔽中断: STI
(4)十进制调整指令
- 运算器按二进制规律进行运算,如果参与运算的是BCD码数,则需要对结果进行调整。
- BCD码有两种:
- 压缩BCD码:用4个二进制位表示一个十进制位,1字节可以表示两个十进制位,即00~99。
- 非压缩BCD码:用8位二进制数表示一个十进制位,实际上只是用低4位二进制数表示一个十进制数0~9,高4位任意,通常默认为0。
a.加法的十进制调整指令DAA(压缩BCD码)
- 格式:DAA
- 功能:AL←将AL中的和调整为压缩的BCD码。该指令跟在以AL为目的操作数的ADD或者ADC指令之后,对AL的二进制结果进行十进制调整,并在AL得到十进制结果。
- 注意:BCD码小于10不调整,BCD码大于9或AF/CF=1,按加6调整。
b.减法的十进制调整指令DAS(压缩BCD码)
- 格式:DAS
- 功能:AL←将AL中的差调整为压缩的BCD码,该指令跟在以AL为目的操作数的SUB或者SBB指令之后,对AL的二进制结果进行十进制调整,并在AL得到十进制结果。
- 注意:BCD码小于10不调整,BCD码大于9或AF/CF=1,按减6调整。
c.加法的十进制调整指令AAA(非压缩BCD码)
- 格式:AAA
- 功能:AL←将AL的和调整为非压缩BCD码。AH←AH+调整产生的进位(AF=1)
d.减法的十进制调整指令AAS(非压缩BCD码)
- 格式:AAS
- 功能: AL←将AL的减差调整为非压缩BCD码。AH←AH-调整产生的借位
e.乘法的十进制调整指令AAM(非压缩BCD码)
- 格式:AAM
- 功能:AX←将AX的乘积调整为非压缩BCD码
f.除法的十进制调整指令AAD(非压缩BCD码)
- 格式:AAD
- 功能:AX←将AX中非压缩BCD码扩展成二进制数,即:AL←10×AH+AL,AH←0