经典的80x86指令系统.docx
《经典的80x86指令系统.docx》由会员分享,可在线阅读,更多相关《经典的80x86指令系统.docx(28页珍藏版)》请在冰豆网上搜索。
![经典的80x86指令系统.docx](https://file1.bdocx.com/fileroot1/2022-11/27/8f4ef67c-6a9d-4679-844c-460fb161cd83/8f4ef67c-6a9d-4679-844c-460fb161cd831.gif)
经典的80x86指令系统
80x86指令系统
80x86的指令系统可以分为以下6组:
数据传送类指令
算术指令
逻辑指令
串处理指令
控制转移指令
处理机控制指令
1、数据传送指令
数据传送类指令负责把数据、地址或立即数传送到寄存器或存储单元中。
它又可以分为五种:
1.1、通用数据传送指令
MOV传送
MOVSX带符号扩展传送
MOVZX带零扩展传送
PUSH进栈
POP出栈
PUSHA所有寄存器进栈
POPA所有寄存器出栈
XCHG交换
(1)MOV传送指令
格式为:
MOVDST,SRC
执行操作:
(DST)<——(SRC)
MOV指令可以在CPU内或CPU和存储器之间传送字或字节,MOV指令不影响标志位
(2)MOVSX带符号扩展传送指令
格式为:
MOVSXDST,SRC
执行操作:
(DST)<——符号扩展(SRC)
该指令的源操作数可以是8位或16位的寄存器或存储单元的内容,而目的操作数则必须是16位或32位寄存器,传送时把源操作数扩展送入目的寄存器。
MOVSX不影响标志位
(3)MOVZX带零扩展传送指令
格式为:
MOVZXDST,SRC
执行操作:
(DST)<——零扩展(SRC)
MOVSX和MOVZX指令与一般双操作数指令的差别是:
一般双操作数指令的源操作数和目的操作数的长度是一致的,但MOVSX和MOVZX的源操作数长度一定要小于目的操作数长度
(4)PUSH进栈指令
格式为:
PUSHSRC
执行操作:
16位指令:
(SP)<——(SP)-2
((SP)+1),(SP))<——(SRC)
32位指令:
(ESP)<——(ESP)-4
((ESP)+3),(ESP)+2),(ESP)+1)(ESP))<——(SRC)
(5)POP出栈指令
格式为:
POPDST
执行操作:
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交换指令
格式为:
XCHGOPR1OPR2
执行操作:
(OPR1)<——>(OPR2)
该指令不影响标志位
1.2、累加器专用传送指令
IN输入
OUT输出
XLAT换码
这组指令只限于使用累加器EAX,AX或AL传送信息
(1)IN输入指令
长格式为:
INAL,PORT(字节)
INAX,PORT(字)
INEAX,PORT(双字)
执行的操作:
(AL)<——(PORT)(字节)
(AX)<——(PORT+1,PORT)(字)
(EAX)<——(PORT+3,PORT+2,PORT+1,PORT)(双字)
短格式为:
INAL,DX(字节)
INAX,DX(字)
INEAX,DX(双字)
执行的操作:
(AL)<——((DX))(字节)
(AX)<——((DX)+1,(DX))(字)
(EAX)<——((DX)+3,(DX)+2,(DX)+1,(DX))(双字)
(2)OUT输出指令
长格式为:
OUTPORT,AL(字节)
OUTPORT,AX(字)
OUTPORT,EAX(双字)
执行的操作:
(PORT)<——(AL)(字节)
(PORT+1,PORT)<——(AX)(字)
(PORT+3,PORT+2,PORT+1,PORT)<——(EAX)(双字)
短格式为:
OUTDX,AL(字节)
OUTDX,AX(字)
OUTDX,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换码指令
格式为:
XALTOPR
执行的操作:
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有效地址送寄存器指令
格式为:
LEAREG,SRC
执行的操作:
(REG)<——SRC
指令把源操作数的有效地址送到指定的寄存器中
(2)LDS、LES、LFS、LGS和LSS指针送寄存器和段寄存器指令
格式为:
LDSREG,SRC
执行的操作:
(REG)<——(SRC)
(SREG)<——(SRC+2)
或(SREG)<——(SRC+4)
该组指令的源操作数只能用于存储器寻址方式,根据任一种存储器寻址方式找到一个存储单元的地址,当指令指定的寄存器是16位寄存器时,把该存储单元中存放的16位偏移地址装入该寄存器中,然后把(SRC+2)中的16位数装入指令指定的段寄存器中;当指令指定的是32位寄存器时,把该存储单元中存放的32位偏移地址装入该寄存器中,然后把(SRC+4)中的16位数装入到指定的段寄存器中
本组指令不影响标志位
1.4、标志寄存器传送指令
LAHF标志送AH
SAHFAH送标志寄存器
PUSHF:
标志进栈
POPF:
标志出栈
(1)LAHF标志送AH指令
格式为:
SAHF
执行的操作:
(AH)<——(FLAGS的低字节)
(2)SAHFAH送标志寄存器
格式为:
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字节交换指令
格式:
BSWAPr32
执行的操作:
使指令指定的32位寄存器的字节次序变反
本组指令不影响标志位
2、算术指令
80x86的算术运算指令包括二进制运算和十进制运算指令
2.1、加法指令
ADD加法
ADC带进位加法
INC加1
XADD交换并相加
(1)ADD加法指令
格式:
ADDDST,SRC
执行的操作:
(DST)<——(SRC)+(DST)
(2)ADC带进位加法指令
格式:
ADCDST,SRC
执行的操作:
DST)<——(SRC)+(DST)+CF
(3)INC加1指令
格式:
INCOPR
执行的操作:
(OPR)<——(OPR)+1
(4)XADDDST,SRC
格式:
XADD交换并相加指令
执行的操作:
TEMP<——(SRC)+(DST)
(SRC)<——(DST)
(DST)<——TEMP
除INC不影响CF标志外,本组指令都影响条件标志位
2.2、减法指令
SUB减法
SBB带借位减法
DEC减1
NEG求补
CMP比较
CMPXCHG比较并交换
CMPXCHG8B比较并交换8字节
(1)SUB减法指令
格式:
SUBDST,SRC
执行的操作:
(DST)<——(DST)-(SRC)
(2)SBB带借位减法
格式:
SBBDST,SRC
执行的操作:
(DST)<——(DST)-(SRC)-CF
(3)DEC减一指令
格式:
DECOPR
执行的操作:
(OPR)<——(OPR)-1
(4)NEG求补指令
格式:
NEGOPR
执行的操作:
(OPR)<——0FFFFH-(OPR)+1
(5)CMP比较指令
格式:
CMPOPR1,OPR2
执行的操作:
(OPR1)-(OPR2)
该指令与SUB指令一样执行减法,但它不保存结果,只是根据结果设置条件标志位。
CMP指令后往往跟着一条条件转移指令,根据比较结果产生不同的程序分支
2.3、乘法指令
MUL无符号数乘法
IMUL带符号数乘法
(1)MUL无符号数乘法指令
格式:
MULSRC
执行的操作:
字节操作数:
(AX)<——(AL)*(SRC)
字操作数:
(DX,AX)<——(AX)*(SRC)
双字操作数:
(EDX,EAX)<——(EAX)*(SRC)
(1)IMUL带符号数乘法指令
格式:
IMULSRC
执行的操作:
与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无符号数除法
格式:
DIVSRC
执行的操作:
字节操作:
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带符号数除法
格式:
IDIVSRC
执行的操作:
与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逻辑与指令
格式:
ANDDST,SRC
执行的操作:
(DST)<——(DST)与(SRC)
(2)OR逻辑或指令
格式:
ORDST,SRC
执行的操作:
(DST)<——(DST)或(SRC)
(3)NOT逻辑非指令
格式:
NOTOPR
执行的操作:
(OPR)<——非(OPR)
(4)XOR异或指令
格式:
XORDST,SRC
执行的操作:
(DST)<——(DST)异或(SRC)
(5)TEST测试指令
格式:
TESTOPR1,OPR2
执行的操作:
(OPR1)与(OPR2)
两个操作数相与的结果不保存,只根据其条件置条件码
NOT指令不影响标志位,其他4种指令将使CF和OF位为0,AF位无定义,而SF、ZF、PF位则根据运算结果设置
3.2、位测试
BT位测试
BTS位测试并置1
BTR位测试并置0
BTC位测试并变反
(1)BT位测试指令
格式:
BTDST,SRC
执行的操作:
把目的操作中由源操作数所指定的值送往标志位CF
(2)BTS位测试并置1指令
格式:
BTSDST,SRC
执行的操作:
把目的操作数中由源操作数所指定的值送往标志位CF,并将目的操作数中该位置1
3.3、位扫描指令
BSF正向扫描指令
BSR反向扫描指令
(1)BSF正向位扫描指令
格式:
BSFREG,SRC
执行的操作:
指令从位0开始自右向左扫描源操作数,目的是检索第一个为1的位。
如遇到第一个为1的位则将ZF置0,并将该位的位位置装入目的寄存器中;如源操作数为0,则将ZF位置1,目的寄存器无定义
3.4、移位指令
SHL逻辑左移
SAL算术左移
SHR逻辑右移
SAR算术右移
ROL循环左移
RPR循环右移
RCL带进位循环左移
RCR带进位循环右移
SHLD双精度左移
SHRD双精度右移
4、串处理指令
MOVS串传送
CMPS串比较
SCAS串扫描
LODS从串取
STOS存入串
INS串输入
OUTS串输出
与上述基本指令配合使用的前缀有:
REP重复
REPE/REPZ相等/为零则重复
REPNE/REPNZ不相等/不为零则重复
4.1、与REP相配合工作的MOVS,STOS,LODS,INC和OUTS指令
(1)REP重复串操作直到计数寄存器CountReg的内容为0为止
格式:
REPstringprimitive
其中,stringprimitive可为MOVS,STOS,LODS,INC和OUTS指令
执行的操作:
如(CountReg)=0,则退出REP,否则往下执行
(CountReg)<——(CountReg)-1
执行其后的串指令
重复上述操作
其中,地址长度为16位时,用CX作为CountReg;地址长度为32位时,用ECX作为CountReg
(2)MOVS串传送指令
格式:
MOVSDST,SRC
MOVSB(字节)
MOVSW(字)
MOVSD(双字)
其中后三种格式明确注明是传送字节、字或双字,第一种格式则应在操作数中表明是双字、字还是字节操作,例如:
MOVSES:
BYTEPTR[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存入串指令
格式:
STOSDST
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的内容存入一个长度为(CountReg)的缓冲区中
(4)LODS从串取指令
LODSSRC
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)串输入指令
格式:
INSDST,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联用时,可以把成组的字节、字或双字输入到长度为(CountReg)的缓冲区中
(6)OUTS串输出指令
格式:
OUTSDX,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联用时,可以把存储器中长度为(CountReg)的字节、字或双字成组地传送到I/O空间
4.2、与REPE/REPZ和REPNE/REPNZ联合工作的CMPS和SCAS指令
(1)REPE/REPZ当相等/为零时重复串操作
格式:
REPE/REPZStringPrimitive
其中,StringPrimitive可为CMPS或SCAS指令
执行的操作:
如(CountReg)=0或ZF=0(即某次比较的结果两个操作数不等)时退出,否则往下执行
(CountReg)<——(CountReg)-1
执行其后的串指令
重复上述操作
与REP相比,除满足(CountReg)=0的条件可结束操作外,还增加了ZF=0的条件。
也就是说,只要两数相等就可继续比较,如果遇到两数不等时可提前结束操作
(2)REPNE/REPNZ当不相等/不为零时重复串操作
格式:
REPNE/REPNZStringPrimitive
其中,StringPrimitive可为CMPS或SCAS指令
执行的操作:
如(CountReg)=0或ZF=1(即某次比较的结果两个操作数相等)时退出,否则往下执行
(3)CMPS串比较指令
格式:
CMPSSRC,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串扫描指令
格式:
SCASDST
SCASB(