您的当前位置:首页正文

资料:经典的80x86指令系统(指令大全)

2024-08-12 来源:小奈知识网


80x86指令系统

80x86的指令系统可以分为以下6组:

数据传送类指令

算术指令

逻辑指令

串处理指令

控制转移指令

处理机控制指令

1、数据传送指令

数据传送类指令负责把数据、地址或立即数传送到寄存器或存储单元中。它又可以分为五种:

1.1、通用数据传送指令

MOV 传送

MOVSX 带符号扩展传送

资源共享

MOVZX 带零扩展传送

PUSH 进栈

POP 出栈

PUSHA 所有寄存器进栈

POPA 所有寄存器出栈

XCHG 交换

(1)MOV传送指令

格式为:MOV DST,SRC

执行操作:(DST)<——(SRC)

MOV指令可以在CPU内或CPU和存储器之间传送字或字节,MOV指令不影响标志位

(2)MOVSX带符号扩展传送指令

格式为:MOVSX DST,SRC

执行操作:(DST)<——符号扩展(SRC)

资源共享

该指令的源操作数可以是8位或16位的寄存器或存储单元的内容,而目的操作数则必须是16位或32位寄存器,传送时把源操作数扩展送入目的寄存器。MOVSX不影响标志位

(3)MOVZX带零扩展传送指令

格式为:MOVZX DST,SRC

执行操作:(DST)<——零扩展(SRC)

MOVSX和MOVZX指令与一般双操作数指令的差别是:一般双操作数指令的源操作数和目的操作数的长度是一致的,但MOVSX和MOVZX的源操作数长度一定要小于目的操作数长度

(4)PUSH进栈指令

格式为:PUSH SRC

执行操作:

16位指令:

(SP)<——(SP)-2

((SP)+1),(SP))<——(SRC)

资源共享

32位指令:

(ESP)<——(ESP)-4

((ESP)+3),(ESP)+2),(ESP)+1)(ESP))<——(SRC)

(5)POP出栈指令

格式为:POP DST

执行操作:

16位指令:

(DST)<——((SP)+1),(SP))

(SP)<——(SP)+2

32位指令:

(DST)<——((ESP)+3),(ESP)+2),(ESP)+1)(ESP))

(ESP)<——(ESP)+4

堆栈是一种“后进先出”方式工作的一个存储区,它必须存在于堆栈段中,因而其段地址存放于SS寄存器中。它只有一个出入口,所以只有一个堆栈指针寄存器。当堆栈地址

资源共享

长度为16位时用SP寄存器,堆栈地址长度为32位时用ESP,SP或ESP的内容在任何时候都指向当前的栈顶,所以POP和PUSH指令都必须根据当前SP或ESP的内容来确定进栈或出栈的存储单元,而且必须及时修改指针,以保证SP或ESP指向当前的栈顶。PUSH和POP指令均不影响标志位

(5)XCHG交换指令

格式为:XCHG OPR1 OPR2

执行操作:(OPR1)<——>(OPR2)

该指令不影响标志位

1.2、累加器专用传送指令

IN 输入

OUT 输出

XLAT 换码

这组指令只限于使用累加器EAX,AX或AL传送信息

(1)IN输入指令

长格式为:

资源共享

IN AL,PORT(字节)

IN AX,PORT(字)

IN EAX,PORT(双字)

执行的操作:

(AL)<——(PORT)(字节)

(AX)<——(PORT+1,PORT)(字)

(EAX)<——(PORT+3,PORT+2,PORT+1,PORT)(双字)

短格式为:

IN AL,DX(字节)

IN AX,DX(字)

IN EAX,DX(双字)

执行的操作:

(AL)<——((DX))(字节)

资源共享

(AX)<——((DX)+1,(DX))(字)

(EAX)<——((DX)+3,(DX)+2,(DX)+1,(DX))(双字)

(2)OUT输出指令

长格式为:

OUT PORT,AL(字节)

OUT PORT,AX(字)

OUT PORT,EAX(双字)

执行的操作:

(PORT)<——(AL)(字节)

(PORT+1,PORT)<——(AX)(字)

(PORT+3,PORT+2,PORT+1,PORT)<——(EAX)(双字)

短格式为:

OUT DX,AL(字节)

资源共享

OUT DX,AX(字)

OUT DX,EAX(双字)

执行的操作:

((DX))<——(AL)(字节)

((DX)+1,(DX))<——(AX)(字)

((DX)+3,(DX)+2,(DX)+1,(DX))<——(EAX)(双字)

在80x86里,所有I/O端口与CPU之间的通信都由IN和OUT指令来完成。其中,IN完成从I/O到CPU的信息传送,而OUT则完成从CPU到I/O的信息传送。CPU只能用累加器(AL,AX,EAX)接收或发送信息。外部设备最多可有65536个I/O端口,端口号为0000~FFFFH。其中的前256个端口可以直接在指令中指定,这就是长格式中的PORT,此时机器指令用两个字节表示,第二个字节就是端口号。当端口号大于等于256时,只能用短格式,此时必须先把端口号放到DX寄存器中,然后再用IN或OUT指令来传送信息。

输入、输出指令不影响标志位

(3)XLAT换码指令

格式为:XALT OPR

资源共享

执行的操作:

16位指令:(AL)<——((BX)+(AL))

32位指令:(AL)<——((EBX)+(AL))

经常需要把一种代码转换为另一种代码。在使用这条指令之前,应先建立一个字节表格,表格的首地址提前存入BX或EBX寄存器,需要转化的代码应该是相对于表格首地址的位移量也提前存放在AL寄存器中,表格的内容则是所要换取的代码,该指令执行后就可在AL中得到转换后的代码

该指令不影响标志位

1.3、地址传送指令

LEA 有效地址送寄存器

LDS 指针送寄存器和DS

LES 指针送寄存器和ES

LFS 指针送寄存器和FS

LGS 指针送寄存器和GS

LSS 指针送寄存器和SS

资源共享

这一组指令完成把地址送到指定寄存器的功能

(1)LEA有效地址送寄存器指令

格式为:LEA REG,SRC

执行的操作:(REG)<——SRC

指令把源操作数的有效地址送到指定的寄存器中

(2)LDS、LES、LFS、LGS和LSS指针送寄存器和段寄存器指令

格式为:LDS REG,SRC

执行的操作:

(REG)<——(SRC)

(SREG)<——(SRC+2)

或(SREG)<——(SRC+4)

该组指令的源操作数只能用于存储器寻址方式,根据任一种存储器寻址方式找到一个存储单元的地址,当指令指定的寄存器是16位寄存器时,把该存储单元中存放的16位偏移地址装入该寄存器中,然后把(SRC+2)中的16位数装入指令指定的段寄存器中;当指令指定的是32位寄存器时,把该存储单元中存放的32位偏移地址装入该寄存器中,然

资源共享

后把(SRC+4)中的16位数装入到指定的段寄存器中

本组指令不影响标志位

1.4、标志寄存器传送指令

LAHF 标志送AH

SAHF AH送标志寄存器

PUSHF:标志进栈

POPF:标志出栈

(1)LAHF标志送AH指令

格式为:SAHF

执行的操作:(AH)<——(FLAGS的低字节)

(2)SAHF AH送标志寄存器

格式为:SAHF

执行的操作:(FLAGS的低字节)<——(AH)

资源共享

1.5、类型转换指令

CBW 字节转换成字

CWD 字转换成双字

CDQ 双字转换为4字

BSWAP 字节交换

(1)CBW字节转换为字指令

格式:CBW

执行的操作:AL的内容符号扩展到AH,形成AX中的字

(2)CWD字转换为双字指令

格式:CWD

执行的操作:AX的内容符号扩展到DX,形成DX:AX中的双字

(3)CDQ双字转换为4字指令

格式:CDQ

资源共享

执行的操作:EAX的内容符号扩展到EDX,形成EDX:EAX中的4字

(4)BSWAP字节交换指令

格式:BSWAP r32

执行的操作:使指令指定的32位寄存器的字节次序变反

本组指令不影响标志位

2、算术指令

80x86的算术运算指令包括二进制运算和十进制运算指令

2.1、加法指令

ADD 加法

ADC 带进位加法

INC 加1

XADD 交换并相加

(1)ADD加法指令

资源共享

格式:ADD DST,SRC

执行的操作:(DST)<——(SRC)+(DST)

(2)ADC带进位加法指令

格式:ADC DST,SRC

执行的操作:DST)<——(SRC)+(DST)+CF

(3)INC加1指令

格式:INC OPR

执行的操作:(OPR)<——(OPR)+1

(4)XADD DST,SRC

格式:XADD交换并相加指令

执行的操作:

TEMP<——(SRC)+(DST)

(SRC)<——(DST)

资源共享

(DST)<——TEMP

除INC不影响CF标志外,本组指令都影响条件标志位

2.2、减法指令

SUB 减法

SBB 带借位减法

DEC 减1

NEG 求补

CMP 比较

CMPXCHG 比较并交换

CMPXCHG8B 比较并交换8字节

(1)SUB减法指令

格式:SUB DST,SRC

执行的操作:(DST)<——(DST)-(SRC)

资源共享

(2)SBB带借位减法

格式:SBB DST,SRC

执行的操作:(DST)<——(DST)-(SRC)-CF

(3)DEC减一指令

格式:DEC OPR

执行的操作:(OPR)<——(OPR)-1

(4)NEG求补指令

格式:NEG OPR

执行的操作:(OPR)<——0FFFFH-(OPR)+1

(5)CMP比较指令

格式:CMP OPR1,OPR2

执行的操作:(OPR1)-(OPR2)

该指令与SUB指令一样执行减法,但它不保存结果,只是根据结果设置条件标志位。CMP指令后往往跟着一条条件转移指令,根据比较结果产生不同的程序分支

资源共享

2.3、乘法指令

MUL 无符号数乘法

IMUL 带符号数乘法

(1)MUL无符号数乘法指令

格式:MUL SRC

执行的操作:

字节操作数:(AX)<——(AL)*(SRC)

字操作数:(DX,AX)<——(AX)*(SRC)

双字操作数:(EDX,EAX)<——(EAX)*(SRC)

(1)IMUL带符号数乘法指令

格式:IMUL SRC

执行的操作:与MUL相同,但必须是带符号数,而MUL是无符号数

在乘法指令里,目的操作数必须是累加器,字运算为AX,字节运算为AL。对于MUL指令,如果乘积的高一半为0,即字节操作的(AH)或字操作的(DX)或双字操作的(EDX)

资源共享

为0,则CF位和OF位均为0;否则,则CF位和OF位均为1。这样的条件码设置可以用来检查字节相乘的结果是字节还是字,或者可以检查字相乘的结果是字还是双字,双字相乘的结果是双字还是4字。对于IMUL指令,如果乘积的高一半是低一半的符号扩展,则CF位和OF位均为0;否则,则CF位和OF位均为1

2.4、除法指令

DIV 无符号数除法

IDIV 带符号数除法

(1)DIV无符号数除法

格式:DIV SRC

执行的操作:

字节操作:16位被除数在AX中,8位除数为源操作数,结果的8位商在AL中,8位余数在AH中。表示为:

(AL)<——(AX)/(SRC)的商

(AH)<——(AX)/(SRC)的余数

字操作:32位被除数在DX,AX中。其中,DX为高位字,16位除数为源操作数,结果的16位商在AX中,16位余数在DX中。表示为:

资源共享

(AX)<——(DX,AX)/(SRC)的商

(DX)<——(DX,AX)/(SRC)的余数

双字操作:64位被除数在EDX,EAX中。其中,EDX为高位字,32位除数为源操作数,结果的32位商在EAX中,32位余数在EDX中。表示为:

(EAX)<——(EDX,EAX)/(SRC)的商

(EDX)<——(EDX,EAX)/(SRC)的余数

商和余数均为无符号数

(2)IDIV带符号数除法

格式:IDIV SRC

执行的操作:与DIV相同,但操作数必须是带符号数,商和余数也是带符号数

2.5、十进制运算指令

二-十进制(BCD)是一种用二进制编码的十进制数。它是用4位2进制数表示一个十进制数码的,由于这4位二进制数的权为8421,所以BCD码又成为8421码。可以用压缩的BCD码和非压缩的BCD两种格式来表示一个十进制数。压缩的BCD码用4位二进制数表示一个十进制数位,整个十进制数形成为一个顺序的以4位为一组的数串。非压缩的BCD码则以8位表示一个十进制数位,8位中的低4位是以8421码表示的十进制数位,

资源共享

而高4位则没有意义

3、逻辑指令

3.1、逻辑运算指令

AND 逻辑与

OR 逻辑或

NOT 逻辑非

XOR 异或

TEST 测试

(1)AND逻辑与指令

格式:AND DST,SRC

执行的操作:(DST)<——(DST)与(SRC)

(2)OR逻辑或指令

格式:OR DST,SRC

资源共享

执行的操作:(DST)<——(DST)或(SRC)

(3)NOT逻辑非指令

格式:NOT OPR

执行的操作:(OPR)<——非(OPR)

(4)XOR异或指令

格式:XOR DST,SRC

执行的操作:(DST)<——(DST)异或(SRC)

(5)TEST测试指令

格式:TEST OPR1,OPR2

执行的操作:(OPR1)与(OPR2)

两个操作数相与的结果不保存,只根据其条件置条件码

NOT指令不影响标志位,其他4种指令将使CF和OF位为0,AF位无定义,而SF、ZF、PF位则根据运算结果设置

3.2、位测试

资源共享

BT 位测试

BTS 位测试并置1

BTR 位测试并置0

BTC 位测试并变反

(1)BT位测试指令

格式:BT DST,SRC

执行的操作:把目的操作中由源操作数所指定的值送往标志位CF

(2)BTS位测试并置1指令

格式:BTS DST,SRC

执行的操作:把目的操作数中由源操作数所指定的值送往标志位CF,并将目的操作数中该位置1

3.3、位扫描指令

BSF 正向扫描指令

BSR 反向扫描指令

资源共享

(1)BSF正向位扫描指令

格式:BSF REG,SRC

执行的操作:指令从位0开始自右向左扫描源操作数,目的是检索第一个为1的位。如遇到第一个为1的位则将ZF置0,并将该位的位位置装入目的寄存器中;如源操作数为0,则将ZF位置1,目的寄存器无定义

3.4、移位指令

SHL 逻辑左移

SAL 算术左移

SHR 逻辑右移

SAR 算术右移

ROL 循环左移

RPR 循环右移

RCL 带进位循环左移

RCR 带进位循环右移

资源共享

SHLD 双精度左移

SHRD 双精度右移

、串处理指令

MOVS 串传送

CMPS 串比较

SCAS 串扫描

LODS 从串取

STOS 存入串

INS 串输入

OUTS 串输出

与上述基本指令配合使用的前缀有:

REP 重复

REPE/REPZ 相等/为零则重复

资源共享

4

REPNE/REPNZ 不相等/不为零则重复

4.1、与REP相配合工作的MOVS,STOS,LODS,INC和OUTS指令

(1)REP重复串操作直到计数寄存器Count Reg的内容为0为止

格式:REP string primitive

其中,string primitive可为MOVS,STOS,LODS,INC和OUTS指令

执行的操作:

如(Count Reg)=0,则退出REP,否则往下执行

(Count Reg)<——(Count Reg)-1

执行其后的串指令

重复上述操作

其中,地址长度为16位时,用CX作为Count Reg;地址长度为32位时,用ECX作为Count Reg

(2)MOVS串传送指令

格式:

资源共享

MOVS DST,SRC

MOVSB (字节)

MOVSW (字)

MOVSD (双字)

其中后三种格式明确注明是传送字节、字或双字,第一种格式则应在操作数中表明是双字、字还是字节操作,例如:

MOVS ES:BYTE PTR[DI],DS:[SI]

执行的操作:

((Destination-index))<——((Source-index))

字节操作:

(Source-index)<——(Source-index)+-1

(Destination -index)<——(Destination -index)+-1

字操作:

(Source-index)<——(Source-index)+-2

资源共享

(Destination -index)<——(Destination -index)+-2

双字操作:

(Source-index)<——(Source-index)+-4

(Destination -index)<——(Destination -index)+-4

上述操作中,当方向标志DF=0时用+,DF=1时用-

其中,Source-index为源变址寄存器,当地址长度为16时用SI寄存器,当地址长度为32时用ESI寄存器;Destination –index为目的变址寄存器,当地址长度为16时用DI寄存器,当地址长度为32时用EDI寄存器

该指令不影响条件码

MOVS指令可以把源变址寄存器指向的数据段中的一个字(或双字,字节)传送到由目的寄存器指向的附加段中的一个字(或双字,字节)中去,同时根据方向标志及数据格式对源变址寄存器和目的变址寄存器进行修改。当该指令与前缀REP联用时,则可将数据段中的整串数据传送到附加段中去

(3)STOS存入串指令

格式:

STOS DST

资源共享

STOSB (字节)

STOSW (字)

STOSD (双字)

执行的操作:

字节操作:

((Destination-index))<——(AL)

(Destination-index)<——(Destination-index)+-1

字操作:

((Destination-index))<——(AX)

(Destination-index)<——(Destination-index)+-2

双字操作:

((Destination-index))<——(EAX)

(Destination-index)<——(Destination-index)+-4

资源共享

该指令把AL、AX、EAX的内容存入由目的变址寄存器指向的附加段的某单元中,并根据DF的值及数据类型修改目的变址寄存器的内容。当它与REP联用时,可把AL、AX或EAX的内容存入一个长度为(Count Reg)的缓冲区中

(4)LODS从串取指令

LODS SRC

LODSB (字节)

LODSW (字)

LODSD (双字)

执行的操作:

字节操作:

(AL)<——((Source-index)),(Source-index)<——(Source-index)+-1

字操作:

(AX)<——((Source-index)),(Source-index)<——(Source-index)+-2

双字操作:

资源共享

(EAX)<——((Source-index)),(Source-index)<——(Source-index)+-4

该指令把由源变址寄存器指向的数据段中某单元的内容送到AL、AX或EAX中,并根据方向标志和数据类型修改源变址寄存器。

(5)串输入指令

格式:

INS DST,DX

INSB

INSW

INSD

执行的操作:

字节操作:

((Destination-index))<——((DX))(字节)

(Destination-index)<——(Destination-index)+-1

字操作:

资源共享

((Destination-index))<——((DX))(字)

(Destination-index)<——(Destination-index)+-2

双字操作:

((Destination-index))<——((DX))(双字)

(Destination-index)<——(Destination-index)+-4

该指令把端口号在DX寄存器中的I/O空间的字节、字或双字送到附加段中的由目的变址寄存器所指向的存储单元中,并根据DF的值和数据类型修改目的变址寄存器的内容。当它与REP联用时,可以把成组的字节、字或双字输入到长度为(Count Reg)的缓冲区中

(6)OUTS串输出指令

格式:

OUTS DX,SRC

OUTSB (字节)

OUTSW (字)

OUTSD (双字)

资源共享

执行的操作:

字节操作:

((DX))<——((Source-index))(字节)

(Source-index)<——(Source-index)+-1

字操作:

((DX))<——((Source-index))(字)

(Source-index)<——(Source-index)+-2

双字操作:

((DX))<——((Source-index))

(Source-index)<——(Source-index)+-4

该指令把由源变址寄存器所指向的存储器中的字节、字或双字传送到端口号在DX寄存器中的I/O端口中去,并根据DF的值和数据类型修改源变址寄存器的内容。当它与REP联用时,可以把存储器中长度为(Count Reg)的字节、字或双字成组地传送到I/O空间

4.2、与REPE/REPZ和REPNE/REPNZ联合工作的CMPS和SCAS指令

资源共享

(1)REPE/REPZ当相等/为零时重复串操作

格式:REPE/REPZ String Primitive

其中,String Primitive可为CMPS或SCAS指令

执行的操作:

如(Count Reg)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行

(Count Reg)<——(Count Reg)-1

执行其后的串指令

重复上述操作

与REP相比,除满足(Count Reg)=0的条件可结束操作外,还增加了ZF=0的条件。也就是说,只要两数相等就可继续比较,如果遇到两数不等时可提前结束操作

(2)REPNE/REPNZ当不相等/不为零时重复串操作

格式:REPNE/REPNZ String Primitive

其中,String Primitive可为CMPS或SCAS指令

资源共享

执行的操作:

如(Count Reg)=0或ZF=1(即某次比较的结果两个操作数相等)时退出,否则往下执行

(3)CMPS串比较指令

格式:

CMPS SRC,DST

CMPSB (字节)

CMPSW (字)

CMPSD (双字)

执行的操作:

((Source-index))-((Destination-index))

字节操作:

(Source-index)<——(Source-index)+-1

(Destination-index)<——(Destination -index)+-1

资源共享

字操作:

(Source-index)<——(Source-index)+-2

(Destination-index)<——(Destination -index)+-2

双字操作:

(Source-index)<——(Source-index)+-4

(Destination-index)<——(Destination -index)+-4

指令把由源变址寄存器指向的数据段中的一个字节、字或双字于由目的变址寄存器所指向的附加段中的一个字节、字或双字相减,但不保存结果,只根据结果置条件码

(4)SCAS串扫描指令

格式:

SCAS DST

SCASB (字节)

SCASW (字)

SCASD (双字)

资源共享

执行的操作:

字节操作:

(AL)(-(Destination -index)),(Destination -index)<——(Destination -index)+-1

字操作:

(AX)(-(Destination -index)),(Destination -index)<——(Destination -index)+-2

双字操作:

(EAX)-((Destination -index)),(Destination -index)<——(Destination -index)+-4

指令把AL、AX或EAX的内容与由变址寄存器指向的在附加段中的一个字节、字或双字进行比较,并不保存结果。只根据结果设置条件码

5、控制转移指令

一般情况下指令是顺序地逐条执行的,但实际上程序不可能完全顺序执行而经常要改变程序的执行流程,这里介绍的控制转移指令就是用来控制程序的执行流程的

5.1、无条件转移指令

资源共享

JMP 跳转指令

无条件地转移到指令指定的地址去执行从该地址开始的指令,JMP指令必须指定转移的目标地址

转移可以分为两类:段内转移和段间转移。段内转移是指在同一段的范围内进行转移,此时只需改变IP或EIP寄存器的内容,用新的转移目标地址代替原有的IP或EIP的值就可达到转移的目的。段间转移则是要转到另一个段去执行程序,此时不仅要修改IP或EIP的寄存器的内容,还需要修改CS寄存器的内容才能达到目的。此时的转移目标地址应由新的段地址和偏移地址两部分组成

(1)段内直接短转移

格式:JMP SHORT OPR

执行的操作:(IP)<——(IP)+8位位移量

其中8位位移量是由目标地址OPR确定的

(2)段内直接近转移

格式:JMP NEAR PTR OPR

执行的操作:(IP)<——(IP)+16位位移量

(3)段内间接近转移

资源共享

格式:JMP WORD PTR OPR

执行的操作:(IP)<——(EA)

其中有效地址由OPR的寻址方式确定,如果指定的是寄存器,则把寄存器的内容送到IP或EIP寄存器中;如果指定的是存储器中的一个字或双字,则把该存储单元的内容送到IP或EIP寄存器中

(4)段间直接远转移

格式:JMP FAR PTR OPR

执行的操作:

(IP)<——OPR的段内偏移地址

(CS)<——OPR所在段的段地址

(5)段间间接转移

格式:JMP DWORD PTR OPR

执行的操作:

(IP)<——(EA)

资源共享

(CS)<——(EA+2)

其中EA由OPR的寻址方式确定,它只能使用存储器寻址方式,根据寻址方式求出EA后,把指定存储单元的字内容送到IP或EIP寄存器,并把下一个字的内容送到CS寄存器,这样就实现了段间转移

JMP指令不影响条件码

5.2、条件转移指令

条件转移指令根据上一条指令所设置的条件码来判别测试条件,每一种条件转移指令都有它的测试条件,满足测试条件则转移到由指令指定的转向地址去执行那里的程序,不满足条件则顺序执行下一条执行。因此,当满足条件时:IP或EIP与8位、16位或32位位移量相加得到转移地址;如不满足测试条件,则IP或EIP值不变

5.2.1、根据单个条件标志的设置情况转移

(1)JZ(或JE)结果为零(或相等)则转移

格式:JZ(或JE) OPR

测试条件:ZF=1

(2)JNZ(或JNE)结果不为零(或不相等)则转移

格式:JNZ(或JNE) OPR

资源共享

测试条件:ZF=0

(3)JS结果为负则转移

格式:JS OPR

测试条件:SF=1

(4)JNS结果为正则转移格式:JNS OPR

测试条件:SF=0

(5)JO溢出则转移

格式:JO OPR

测试条件:OF=1

(6)JNO不溢出则转移

格式:JNO OPR

测试条件:OF=0

资源共享

(7)JP奇偶位为1则转移

格式:JP OPR

测试条件:PF=1

(8)JNP奇偶位为0则转移

格式:JNP OPR

测试条件:PF=0

(9)JC进位位为1则转移

格式:JC OPR

测试条件:CF=1

(9)JNC进位位为0则转移

格式:JNC OPR

测试条件:CF=0

5.2.2、比较两个无符号数,并根据比较的结果转移

资源共享

(1)JB(或JNAE,或JC)低于,或者不高于或等于,或进位位为1则转移

格式:JB OPR

测试条件:CF=1

(2)JNB(或JAE,或JNC)不低于,或者高于或等于,或进位位为0则转移

格式:JNB OPR

测试条件:CF=0

(3)JBE(或JNA)低于或等于,或不高于则转移

格式:JBE OPR

测试条件:CF或ZF=1

(4)JNBE(或JA)不低于或等于,或高于则转移

格式:JBE OPR

测试条件:CF或ZF=0

5.2.3、比较两个带符号数,并根据比较的结果转移

资源共享

(1)JL(或JNGE)小于,或者不大于或等于则转移

格式:JL OPR

测试条件:SF异或OF=1

(2)JNL(或JGE)不小于,或者大于或等于则转移

格式:JNL OPR

测试条件:SF异或OF=0

(3)JLE(或JNG)小于或等于,或者不大于则转移

格式:JLE(或JNG) OPR

测试条件:(SF异或OF)或ZF=1

(4)JNLE(或JG)不小于或等于,或者大于则转移

格式:JNLE(或JG) OPR

测试条件:(SF异或OF)或ZF=0

5.2.4、测试CX或ECX的值为0则转移指令

资源共享

(1)JCXZ CX寄存器的内容为零则转移

格式:JCXZ OPR

测试条件:(CX)=0

(2)JECXZ ECX寄存器的内容为零则转移

格式:JECXZ OPR

测试条件:(ECX)=0

5.3、条件设置指令

条件转移指令是根据上一条刚执行完的指令所设置的条件码情况,来判断是否产生程序分支的。有时并不希望在这一点就产生程序分支,而是希望在其后运行的程序的另一个位置,根据这一点条件码设置来产生程序分支,这样就要求把这一点的条件码情况保存起来,以便在其后使用,条件设置指令就是根据这样的要求建立的

指令格式:SETcc DST

执行的操作:DST可使用寄存器或任一种存储器寻址方式,但只能指定一个字节单元。指令根据所指定的条件码情况,如满足条件则把目的字节置为1;否则,置为0

5.4、循环指令

资源共享

(1)LOOP循环指令

格式:LOOP OPR

测试条件:(Count Reg)不=0

(2)LOOPZ/LOOPE当为零或相等时循环

格式:LOOPZ OPR

测试条件:ZF=1且(Count Reg)不=0

(3)LOOPNZ/LOOPNE当为零或相等时循环

格式:LOOPNZ OPR

测试条件:ZF=0且(Count Reg)不=0

这三条指令的执行步骤是:

(Count Reg)<——(Count Reg)-1

检查是否满足测试条件,如满足且操作属长度为16位时,则(IP)<——(IP)+D8的符号扩展;如满足且操作属长度为32位时,则(EIP)<——(EIP)+D8的符号扩展

在汇编格式中,OPR必须指定一个表示转向地址的标号(符号地址),而在机器指令

资源共享

里则用8位位移量D8 表示转向地址于当前IP值的差。当满足测试条件时就转向由OPR指定的转向地址去执行,即执行循环;如不满足测试条件,则IP值不变,即退出循环,程序继续顺序执行

Count Reg为计数寄存器,如地址长度为16位,则用CX寄存器,否则用ECX寄存器

循环指令不影响条件码

5.5、子程序

子程序结构相当于高级语言中的过程,为便于模块化程序设计,往往程序中某些具有独立功能的部分编写成独立的程序模块,称为子程序。程序中可由调用程序调用这些子程序,而在子程序执行完后又返回调用程序继续执行。为了实现这一功能,80x86提供了一下指令:

CALL 调用

RET 返回

由于子程序与调用程序可以在一个段中,也可以不在同一段中,因此这两条指令的格式如下:

5.5.1、CALL调用指令

(1)段内直接近调用

资源共享

格式:CALL DST

执行的操作:

Push(IP)

(IP)<——(IP)+D16

这条指令的第一步操作是把子程序的返回地址存入堆栈中,以便子程序返回主程序时使用。第二步操作则是转移到子程序的入口地址去继续执行。指令中DST给出转向地址,D16即为机器指令中的位移量,它是转向地址和返回地址之间的差值

(2)段内间接近调用

格式:CALL DST

执行的操作:

Push(IP)

(IP)<——(EA)

指令中的DST可使用寄存器寻址方式和任一种存储器寻址方式,由指定寄存器或存储单元中的内容给出转向地址

(3)段间直接远调用

资源共享

格式:CALL DST

执行的操作:

Push(IP)

Push(CS)

(IP)<——DST指定的偏移地址

(CS)<——DST指定的段地址

指令先保留返回地址,然后转移到由DST指定的转向地址去执行。由于调用程序和子程序不在同一段内,因此返回地址的保存以及转向地址的设置都必须把段地址考虑在内

(4)段间间接远调用

格式:CALL DST

执行的操作:

Push(IP)

Push(CS)

(IP)<——(EA)

资源共享

(CS)<——(EA+2)

其中EA是由DST的寻址方式确定的有效地址,可以使用任一种存储器寻址方式来取得EA值

5.5.2、RET返回指令

RET指令放在子程序的末尾,它使子程序在功能完成后返回调用程序继续执行,而返回地址是调用程序调用子程序时存放在堆栈中的,因此RET指令的操作是返回地址出栈送IP寄存器和CS寄存器

(1)段内近返回

格式:RET

执行的操作:(IP)<——POP

(2)段内带立即数近返回

格式:RET EXP

执行的操作:

(IP)<——POP

(SP)<——(SP)+D16

资源共享

其中EXP是一个表达式,根据它的值计算出来的常数成为机器指令中的位移量D16。这种指令允许返回地址出栈后修改堆栈的指针,这就便于调用程序在用CALL指令调用子程序以前把子程序所需要的参数入栈,以便子程序运行时使用这些参数。当子程序运行完后,这些参数已不再有用,就可以修改指针使其指向参数入栈以前的值

(3)段间远返回

格式:RET

执行的操作:

(IP)<——POP

(CS)<——POP

(4)段间带立即数远返回

格式:RET EXP

执行的操作:

(IP)<——POP

(CS)<——POP

(SP)<——(SP)+D16

资源共享

CALL和RET指令不影响条件码

5.6、中断

有时当系统运行或者程序运行期间在遇到某些特殊情况时,需要计算机自动执行一组专门的例行程序来进行处理。这种情况称为中断,所执行的这组程序称为中断例行程序或中断子程序。中断分为内部中断和外部中断两类。内部中断包括像除法运算中需要除以0时所产生的中断,或者程序中为了做某些处理而设置的中断指令等,外部中断则主要用于处理I/O设备与CPU之间的通信

当CPU响应一次中断时,也要和调用子程序时类似地把(IP)和(CS)保存入栈,除此之外,为了能全面地保存现场信息,以便在中断处理结束时返回现场,还需要把反映现场状态的(FLAGS)保存入栈,然后才能转到中断例行程序去执行。当然从中断返回时,除要恢复(IP)和(CS)外,还需要恢复(FLAGS)

中断例行程序的入口地址称为中断向量。在80x86中,在实模式工作时,存储器的低地址区的1024个字节(地址从00000H到003FFH)为中断向量区,其中存放着256种类中中断例行程序的入口地址(中断向量)。每种类型的中断向量占用四个字节,包含类型N的中断例行程序的CS和IP

(1)INT中断指令

格式:INT TYPE

执行的操作:

资源共享

PUSH(FLAGS)

IF<——0

TF<——0

AC<——0

Push(CS)

Push(IP)

(IP)<——(TYPE*4)

(CS)<——(TYPE*4+2)

其中TYPE为类型号,它可以是常数或常数表达式,其值必须在0~255范围内。INT指令不影响除IF、TF和AC以外的标志位

(2)INFO若溢出则中断指令

格式:INFO

执行的操作:

若OF=1,则:

资源共享

PUSH(FLAGS)

IF<——0

TF<——0

AC<——0

Push(CS)

Push(IP)

(IP)<——(10H)

(CS)<——(12H)

(3)IRET从中断返回指令

格式:IRET

执行的操作:

(IP)<——POP

(CS)<——POP

资源共享

(FLAGS)<——POP

(4)IRETD从中断返回指令

格式:IRETD

执行的操作:

(EIP)<——POP

(CS)<——POP

(EFLAGS)<——POP

6、处理机控制与杂项操作指令

6.1、标志处理指令

除有些指令影响标志位外,80x86还提供了一组设置或清除标志位指令,它们只影响本指令指定的标志,而不影响其它标志位

CLC 进位位置0指令 CF<——0

CMC 进位位求反指令 CF<——!CF

CTC 进位位置1指令 CF<——1

资源共享

CLD 方向标志位置0指令 DF<——0

CTD 方向标志位置1指令 DF<——1

CLI 中断标志置0指令 IF<——0

CTI 中断标志置0指令 IF<——1

6.2、其它处理机控制与杂项操作指令

NOP 无操作

HLT 停机

ESC 换码

WAIT 等待

LOCK 封锁

BOUND 界限

ENTER 建立堆栈桢

LEAVE 释放堆栈桢

资源共享

(1)NOP无操作指令

该指令不执行任何操作,其机器码占用一个字节单元,在调试程序时往往用这条指令占用一定的存储单元,以便在正常运行时用其它指令取代

(2)HLT停机指令

该指令可使机器暂停工作,使处理机处于停机状态以等待一次外部中断的到来,中断结束后可继续执行下面的程序

(3)WAIT等待指令

该指令使处理机处于空转状态,它也可以用来等待外部中断发生,但中断结束后仍返回WAIT指令继续等待

(4)LOCK指令

该指令是一种前缀,它与其他指令联合,用来维持总线的锁存信号直到与其联合的指令执行完毕为止

(5)BOUND界限指令

格式:BOUND reg,mem

执行的操作:BOUND指令检查给出的数组下标是否在规定的上下界之内,如在上下界之内,则执行下一条指令;如超出了上下界范围,则产生中断5。如发生中断,则中断

资源共享

返回后返回地址仍指向BOUND指令,而不是下一条指令

指令中的第一个操作书必须使用寄存器,用来存放当前数组下标。第二个操作数必须使用存储器寻址方式,该操作数用来存放数组的上下界。当操作数长度为16时,使用相继的两个16位字存放下界和上界,下界存放在低地址所指定的字单元中,上界存放在高地址所指定的字单元中

(6)ENTER建立堆栈桢指令

ENTER指令用于过程调用时为便于过程间传递参数而建立堆栈桢使用。堆栈桢是一个动态存储区

格式:ENTER imm16,imm8

执行的操作:指令中给出的两个操作数均为立即数。第一个操作数为16位立即数,由其指定堆栈桢的大小,即其所占据的字节数。第二个操作数为8位立即数,它给出过程的嵌套层数。该指令完成以下操作:

Push(BP),以保存该寄存器的内容

(BP)<——(SP)使BP寄存器保存当前堆栈指针的内容,以便在运行过程期间,以BP为基准访问堆栈桢中存放的变量

(SP)<——(SP)-imm16,这样就建立了堆栈桢所占有的存储空间

该指令一般位于过程的入口点,为过程建立起堆栈桢,便于存放过程的局部变量,也

资源共享

便于过程间参数的传递。

(7)LEAVE释放堆栈桢指令

LEAVE指令在程序中位于退出过程RET指令之前,用来释放由ENTER指令建立的堆栈桢存储区

格式:LEAVE

执行的操作:

(SP)<——(BP)

(BP)<——POP

资源共享

因篇幅问题不能全部显示,请点此查看更多更全内容