通用传送指令
通用传送指令主要是MOV、MOVZX、MOVSX、XCHG、PUSH、POP、POPA。
MOV指令是以前的处理器就有的,MOVZX和MOVSX是新增的。这两条指令支持不同长度的寄存器之间或寄存器与内存之间的数据传送。例如:
MOVZX EAX,BL
MOVZX DWORD PTR[MEM],AX
MOVSX BX,AL
MOVSX WORD PTR[MEM],AL
MOVZX按无符号扩展来传送,即扩展的高位置0;MOVSX则按带符号扩展来传送,即原来最高位是什么,则扩展后的位就补什么,例如:
MOV AL,70H
MOVZX AX,AL ;AX得0070H
MOVSX AX,AL ;AX得0070H
MOV AL,80H
MOVZX AX,AL ;AX得0080H
MOVSX AX,AL ;AX得FF80H
XCHG是数据交换指令,如:
XCHG EAX,EDX ;交换EAX和EDX的内容
PUSH、POP、PUSHA、POPA是堆栈操作指令。其中PUSH和POP除了增加对32位的扩展外,还增加了支持立即数的操作,例如:
PUSH DWORD PTR 34567
指令PUSHA或POPA是英语PUSH ALL和POP ALL的缩写,它们一次过把所有通用寄存器压栈和出栈。
它有两种形式PUSHA、PUSHAD及POPA、POPAD,分别是对16位和32位寄存器进行栈操作。
PUSHAD的入栈顺序是:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI,PUSHA与此类似。
2. 累加器传送指令
累加器的传送指令有IN、OUT、XLAT三条。
IN和OUT指令与8086的使用方法一样;XLAT则对32位寻址作了扩展,可以是XLAT和XLATB,其中XLAT以BX为基地址,XLATB是以EBX为基地址。
3. 标志传送指令
标志传送指令有以下四条:LAHF、SAHF、PUSHF、POPF。
其中PUSHF和POPF对32位标志寄存器作了扩展:PUSHFD、POPFD。这两组指令分别对16位和32位的标志寄存器FLAG和EFLAG进行压栈和出栈操作。
4. 地址传送指令
地址传送指令有5个:LDS、LES、LFS、LGS、LSS。它们把存储器中的内容送入段寄存器和指定的通用寄存器。其中LFS和LGS是为新增的两个段存器而设的。其使用如下:
LFS EBS,MEMORY1
LGS EDI,MEMORY2
5. 数据类型转换指令
数据类型转换指令包括:CBW、CWD、CWDE、CDQ。它们的功能如下:
CBW ;AL带符号扩展到AX
CWD ;AX带符号扩展到DX和AX
CWDE ;AX带符号扩展到EAX
CWQ ;EAX带符号扩展到EDX和EAX
6. 算术运算指令
80386指令系统的算术运算指令与8086并没有很大的区别,最大的改变只是对32位寄存器的支持。例如;
ADD EAX,EBX
7. 逻辑指令
逻辑指令包括NOT、AND、OR、XOR、TEST、SHL、SHR、SAL、SAR、ROL、ROR、RCL、RCR、SHRD、SHLD。前面的13个指令是8086中就有的,但它们增加了对32位寄存器的支持。移位指令还增加了一个特征,即对大于1的立即数的支持,例如要将AX左移3位,在8086中必须写成:
MOV CL,3
SHL AX,CL
但现在可以直接写成:
SHL AX,3
最后两个指令是80386指令系统新增的64位移位指令,例如:
SHLD EAX,EBX,10 ;EAX左移10位,低10位由EBS高10位补上,
;EBX不变
SHRD EAX,EBX,10 ;EAX右移10位,高10位由EBX低10位补上,
;EBX不变
需要注意,这2条指令不改变第二个操作数。
8. 串操作指令
串操作指令包括 MOVS、CMPS、SCAS、LODS、STOS、INS、OUTS。前5个指令是8086中原有的,在80386指令系统增加了对32位寄存器的支持,如MOVS可以写成MOVSB、MOVSW、MOVSD。它们的源变址寄存器、目的变址寄存器及计数器是用ESI、EDI、ECX还是用SI、DI、CX,由它所在的段决定。若是32位段,则使用前者,否则使用后者。
新增的INS和OUTS指令,可以是INSB、INSW、INSD和OUTSB、OUTSW、OUTSD,用它们对端口输入/输出连续的字符串,变址寄存器是ESI,端口号要放在EDX中。
9. 控制转移指令
控制转移指令包括如JMP、JZ、JB、LOOP、CALL、RET、INT、INTO、IRET等,它们与在8086中的意义基本相同。
但是,JZ、JB等条件跳转指令的跳转范围不再局限在-128~127之间,而与JMP指令一样,不过,这时生成的指令长度要长一些。
80386指令系统针对JCXZ指令增加了一个指令JECXZ。它的跳转条件是以ECX是否为0,而不是以CX是否为0作为标准。这个指令的跳转范围也仍然是-128~127。
循环指令LOOP的跳转范围也仍然是-128~127。
10. 条件设置指令
80386指令系统新增了条件设置指令,用于支持编译程序和高级语言生成的代码。这些指令根据当前的EFLAG中的标志,来设置对应的寄存器或存储器。例如下面的指令,当EAX与EBX相等时设置AL为1,否则为0:
CMP EAX,EBX
SETZ AL
条件设置指令如表5.1所示,条件设置指令的一般格式为:
SETcc OPRD
其中cc泛指所有的条件设置指令。
11. 标志指令
标志指令与8086一样,包括CLC、STC、CMC、CLD、STD、CLI、STI。
12.位处理指令
80386指令系统新增位处理指令,他们的处理对象是位,而不是通常的字节,字或双字。它们的功能如表5.2所示。前4条叫测试和设置指令。其一般格式为:
BTc OPRD1,OPRD2
其中的c泛指这4位指令。如:
BT AX,3
表5.1 80386指令系统新增条件设置指令的功能
指 令 |
功 能 |
SETZ或SETE |
ZF=1则置1 |
SETS |
SF=1则置1 |
SETO |
OF=1则置 |
SETP或SETPE |
PF=1则置 |
SETB或SETNAE或SETC |
CF=1则置 |
SETBE或SETNA |
CF=1或ZF=1则置1 |
SETL或SETNGE |
SF和OF不相等则置1 |
SETLE或SETNGE |
SF和OF不相等或ZF=1则置1 |
SETNZ或SETNE |
ZF=0则置1 |
SETNS |
SF=0则置1 |
SETNO |
OF=1则置1 |
SETNP或SETPO |
PF=0则置1 |
SETNB或SETAE或SETNC |
CF=0则置1 |
SETNBE或SETA |
CF=0且ZF=0则置1 |
SETNL或SETGE |
SF和OF相等则置1 |
SETNLE或SETG |
SF和OF相等且ZF=0则置1 |
13. 处理器控制与特权指令
处理器控制与特权指令包括HLT、WAIT、ESC、NOP和控制寄存器存取指令。控
表5.2 80386指令系统新增位处理指令的功能
指 令 |
功 能 |
BTS |
将测试位的值送CF,并把指定的测试位置1 |
BTR |
将测试位的值送CF,并把指定的测试位置0 |
BTC |
将测试位的值送CF,并把指定的测试位取反 |
BT |
测试指定的位,并将测试位的值送CF |
BSF |
从低到高扫描目标,如果全为0则ZF置1,否则ZF置0,并把为1的位的序号放入目的的寄存器 |
BSR |
从高到低扫描目标,如果全为0则ZF置1,否则ZF置0,并把为1的位的序号放入目的的寄存器 |
制寄存器存取指令如下:
MOV EAX,CR0
MOV CT0,EAX
MOV EAX,DR0
MOV DR0,EAX
MOV EAX,TR6
MOV TR6,EAX
注意CRn和DRn等几个寄存器只能用MOV指令来存取,其它如PUSH、POP、ADD等指令都不能对它们执行存取操作。
14. 高级语言支持指令
80386指令系统新增了3个高级语言支持指令:BOUND、ENTER和LEAVE。
BOUND用于检查数组是否越界,例如,下面的指令检查ESI是否在100与200之间,如果不是,则产生异常5:
MEM DD 100,200
……
BOUND ESI,MEM
ENTER和LEAVE指令用于子程序中建立和释放堆栈框架。在C等高级语言中,函数或过程不仅通过堆栈传递入口参数,而且它们的局部变量也被安排在堆栈中,为了方便地获取入口参数和准确地存取局部变量,就要建立合适的堆栈框架。
ENTER的一般格式为:
ENTER CNT1,CNT2
CNT1为立即数,表示所建立的堆栈框架的字节数,CNT2表示表示子程序嵌套的级别。如:
ENTER 8,0
LEAVE为无操作数指令,用在子程序的结束,但不能代替RET指令。ENTER指令放在子程序的开始。
15. 系统设置和测试指令
系统设置和测试指令在8086中都没有,下面是对它们的描述:
CLTS :清除CR0中的TS位,这是特权指令,只能在0环执行
SGDT :保存GDTR的内容。如SGDT [BX]
SLDT :保存LDTR的内容
SIDT :保存IDTR
LTR :装入任务寄存器
STR :保存任务寄存器
LAR :把源选择子的访问权限装入目的寄存器
LSL :把源选择子的段界限装入目的寄存器
LGDT :装入GDTR。如LGDT [BX]
LLDT :装入LDTR
LIDT :装入IDTR
VERR :检查选择子是否可读
VERW :检查选择子是否可写
LMSW :装入MSW
SMSW :保存MSW
ARPL :调整ARPL
这些指令用作保护模式的支持。