4.2 80x86/Pentium指令系统 4.2.1 80x86寻址方式 1.比例变址寻址方式 (Scaled Indexed Addressing) 操作数的有效地址是变址寄存器的内容乘以指令中指定的比例因子再加上位移量之和,所以有效地址由三种成分组成。这种寻址方式与相对寄存器寻址相比,增加了比例因子,其优点在于:对于元素大小为2,4,8字节的数组,可以在变址寄存器中给出数组元素下标,而由寻址方式控制直接用比例因子把下标转换为变址值。例如:MOV EAX,COUNT[ESI*4]
图4.28 比例变址寻址方式的指令执行情况
2.基址比例变址寻址方式(Based Scaled Indexed Addressing) 操作数的有效地址是变址寄存器的内容乘以比例因子再加上基址寄存器的内容之和,所以有效地址由三种成分组成。这种寻址方式与基址变址寻址方式相比,增加了比例因子,其优点是很明显的,读者可自行推断。例如: MOV ECX,[EAX][EDX*8]
3.相对基址比例变址寻址方式(Relative Based Scaled Indexed Addressing) 操作数的有效地址是变址寄存器的内容乘以比例因子,加上基址寄存器的内容,再加上位移量之和,所以有效地址由四种成分组成。这种寻址方式比相对基址变址寻址方式增加了比例因子,便于对元素为2,4,8字节的二维数组的处理。例如: MOV EAX,TABLE[EBP][EDI*4]
4.2.2 80286增强与增加的指令 1.堆栈操作指令PUSH/PUSHA/POPA 指令格式: PUSH imm16 PUSHA POPA
表4.8 80286增强与增加的指令
PUSH指令允许将字立即数压入堆栈,如果给出的数不够16位,它会在自动扩展后压入堆栈。 PUSHA,POPA指令将所有通用寄存器的内容压入或弹出堆栈。压入的顺序是:AX,CX,DX,BX,SP,BP,SI,DI(SP是执行该指令之前的值),弹出的顺序与压入的相反。
2.有符号数乘法指令IMUL 在80286中允许该指令有两个或三个操作数。其指令格式有两种。 指令格式一: IMUL OPRD1,OPRD2 reg16,reg16 ;reg16为16位寄存器 reg16,mem16 ;mem16为16位存储器 reg16,imm ;imm为8位或16位立即数 功能:用OPRD1乘以OPRD2,返回的积存放在OPRD1指定的寄存器中。
指令格式二: IMUL OPRD1,OPRD2,OPRD3 reg16,regl6,imm reg16,meml6,imm 功能:用OPRD2乘以OPRD3,返回的积存放在OPRD1指定的寄存器中。
两种形式中,对乘积都限制其长度与OPRD1的要一致(为16位有符号数),如果溢出,则溢出部分丢掉,并置CF=OF=1。例如: IMUL BX,CX ;(BX)←(BX)(CX) IMUL BX,50 ;(BX)←(BX)50 IMUL AX,[BX+DI],0342H ;(AX)←0342H(DS:[BX+DI]) IMUL AX,BX,20 ;(AX)←20(BX)
3. 移位和循环移位指令SHL等 指令格式: SHL/SHR/SAL/SAR/ROL/ROR/RCL/RCR OPRD1,OPRD2 reg,imm8 mem,imm8 在8086/8088中规定所有8条移位和循环移位指令中计数值部分或是常数1或是CL中所规定的次数。80286扩充其功能为计数值可以是范围为1~31的常数。例如: SAR DX,3 ROL BYTE PTR[BX],10
4. 串输入/输出指令INS/OUTS 1) 串输入指令INS 指令格式: [REP] INS [ES:]DI,DX [REP] INSB [REP] INSW
INS指令从DX指出的外设端口输入一个字节或字到由ES:DI指定的存储器中,输入字节或字由ES:DI目的操作数的属性决定,且根据方向标志DF和目的操作数的属性来修改DI的值。若方向标志位DF=0, 则DI加1 (字节操作)或加2 (字操作); 否则DI减1或减2。 INSB,INSW分别从DX指出的端口输入一个字节或一个字到由ES:DI指定的存储单元,且根据方向标志DF和串操作的类型来修改DI的值。 这三种形式的指令都可在其前面加重复前缀REP来连续实现整个串的输入操作,这时CX寄存器中为重复操作的次数。
例4.18 从端口PORT输入100个字节,存放到附加数据段以TABLE为首地址的内存单元中。程序段如下: CLD LEA DI,TABLE MOV CX,100 MOV DX,PORT REP INSB
2) 串输出指令OUTS 指令格式: [REP] OUTS DX,[seg:]SI [REP] OUTSB [REP] OUTSW 串输出指令与串输入指令的操作相反,它将[seg:]SI指定的存储单元中的一个字节或字输出到DX指定的外设端口,且根据方向标志DF和源串的类型自动修改SI的值。在其前面加重复前缀REP可连续实现整个串的输出操作,直至CX寄存器的内容减至零。
5. 高级语言类指令 80286提供了三条类似于高级语言的指令。 1) 数组边界检查指令BOUND 指令格式: BOUND OPRD1,OPRD2 reg16,mem16
BOUND指令用于验证指定寄存器OPRD1中的操作数是否在OPRD2(存储器操作数)所指向的两个界限内。若不在,则产生一个5号中断。指令中假定上、下界值(即数组的起始和结束地址)依次存放在相邻存储单元中。例如: ARRAY DW 0000H,0063H ;定义数组的最小下标0及最大下标99 NUMB DW 0019H MOV BX,NUMB ;BX中为被测下标值25 BOUND BX,ARRAY ;检查被测下标值是否在规定的下标边界范围之内
2) 进入和退出过程指令ENTER/LEAVE 指令格式: ENTER OPRD1,OPRD2 imm16,imm8 LEAVE
ENTER指令为局部变量建立一个堆栈区,指令的OPPD1指出程序所要使用的堆栈字节数,OPRD2指出子程序的嵌套层数:0~31。 LEAVE指令用于撤消前面ENTER指令的动作,该指令无操作数。 上面两条指令使用如下: TASK PROC NEAR ENTER 6,0 ;建立堆栈区并保存6个字节长的局部变量 LEAVE ;撤消建立的栈空间 RET TASK ENDP …
4.2.3 80386/80486增强与增加的指令 80386对8086/8088和80286指令系统进行了扩充。这种扩充不仅体现在增加了指令的种类、增强了一些指令的功能,也体现在提供了32位寻址方式和对32位数据的直接操作方式。80486是在80386体系结构的基础上进行了一些扩展,增加了一些相应的指令。因此,所有从8086/8088和80286延伸而来的指令均适用于80386/80486的32位寻址方式和32位操作方式,即所有16位指令都可以扩展为32位的指令。表4.9列出了80386/80486增强与增加的指令。
表4.9 80386/80486增强与增加的指令
1.数据传送类 1) 扩展传送指令MOVSX/MOVZX 指令格式: MOVSX/MOVZX OPRD1,OPRD2 reg16,reg8 reg16,mem8 reg32,reg8 reg32,mem8 reg32,reg16 reg32,mem16
指令的目的操作数必须是16位或32位的通用寄存器,源操作数可以是8位或16位的寄存器或存储器操作数,且要求源操作数的长度小于目的操作数的长度。 MOVSX用于传送有符号数,它将源操作数的符号位扩展后传送到目的操作数。MOVZX用于传送无符号数,它将高位扩展相应位的0后传送到目的操作数。例如: MOVSX ECX,AL ;将AL内容带符号扩展为32位送入ECX MOVZX EAX,CL ;将CL中8位数加0扩展为32位送入EAX 这两条指令常用于作除法时对被除数位数的扩展。
2) 字节交换指令BSWAP 指令格式: BSWAP reg32 功能:将32位通用寄存器中的双字以字节为单位进行高、低字节交换,改变双字数据的存放方式。指令执行时,将字节0(b0~b7)与字节3(b24~b31)交换,字节1(b8~b15)与字节2(b16~b23)交换。
2.算术运算类 1) 交换加法指令XADD 指令格式: XADD OPRD1,OPRD2 reg,reg mem,reg XADD指令将OPRD1 (8位、16位或32位寄存器或存储单元)中目的操作数与OPRD2(8位、16位或32位寄存器)的值相加,结果送入OPRD1,并将OPRD1的原值存于OPRD2。
2) 比较并交换指令CMPXCHG 指令格式: CMPXCHG OPRD1,OPRD2 reg,reg mem,reg CMPXCHG将存放在OPRD1(8位、16位或32位寄存器或存储器)中的目的操作数与累加器AL、AX或EAX的内容进行比较,如果相等,则ZF=1,并将源操作数OPRD2送入OPRD1;否则ZF=0,并将OPRD1送到相应的累加器。例如: CMPXCHG ECX,EDX ;若ECX=EAX,则EDX→ECX,且ZF=1; ;否则,ECX→EAX,且ZF=0
3.逻辑运算与移位指令 双精度左移/右移指令SHLD/SHRD 指令格式: SHLD/SHRD OPRD1,OPRD2,OPRD3 reg,reg,imm8 mem,reg,imm8 reg,reg,CL mem,reg,CL
SHLD/SHRD指令将OPRD1和OPRD2两个16位或32位操作数(寄存器或存储器)连接成双精度值(32位或64位),然后向左或向右移位,移位位数由计数操作OPRD3决定(CL或立即数)。移位时,OPRD2的内容移入OPRD1,而OPRD2本身不变。进位CF中的值为OPRD1移出的最后一位。其操作示意图如图4.29所示。 图4.29 双精度位移示意图
例如: MOV AX,3AF2H MOV BX,9C00H SHLD AX,BX,7 ;指令执行后,AX=794EH,BX=9C00H
4.位操作类 1) 测试与置位指令BT/BTC/BTS/BTR 指令格式: BT/BTC/BTS/BTR OPRD1,OPRD2 reg,reg mem,reg reg,imm mem,imm
这四条指令的功能是:对由OPRD2指定的目的操作数OPRD1(16位或32位)中的某一位(最低位为b0)进行测试操作并送入CF,然后将该位按操作规定置1、置0或变反。当OPRD1是16位操作数时,OPRD2的取值范围为015;当OPRD1是32位操作数时,OPRD2的取值范围为031。 ① BT指令只完成上述位测试并将该位送入CF。
… 例4.19 ② BTC指令在完成BT指令功能后,再将测试位变反。 ③ BTS/BTR完成BT指令功能后,再将测试位置1或置0。 MOV CX,4 BT [BX],CX ;检查由BX指向的数的b4位,且将b4位放入CF中 JC NEXT ;b4位=1,转移至NEXT NEXT: … ② BTC指令在完成BT指令功能后,再将测试位变反。 ③ BTS/BTR完成BT指令功能后,再将测试位置1或置0。 …
2) 位扫描指令BSF/BSR 指令格式: BSF/BSR OPPD1,OPRD2 reg,reg reg,mem BSF用于对16位或32位源操作数OPRD2从低位b0到高位(b15或b31)进行扫描,并将扫描到的第一个“1”的位号送入OPRD1指定的目标寄存器。如果OPRD2所有位均为0,则将ZF标志位置1,OPRD1中的结果无定义;否则(OPRD2≠0),将ZF清0,OPRD1中为位号。
BSR指令的功能同BSF,只是从高位到低位进行反向扫描。例如: MOV BX,40A0H BSF AX,BX ;指令执行后,(AX)=5 BSR AX,BX ;指令执行后,(AX)=14
5.条件设置指令SET 指令格式: SETcc OPRD reg8 mem8 SET类指令共有16条。它们总的功能是,根据指令中给出的条件“CC”是否满足来设置OPRD指定的8位寄存器或存储器操作数:条件满足时,将OPRD操作数置为1;条件不满足时置为0。具体如表4.10所示。
表4.10 条件设置指令表
6.Cache管理类指令 80486的系统控制指令集中增加了三条Cache(高速缓存)管理指令INVD、WBINVD及INVLPG,用于管理CPU内部的8 KB Cache。 1) 作废Cache指令INVD 该指令用于将片内Cache的内容作废。其具体操作是:清除片内Cache的数据,并分配一个专用总线周期清除外部Cache子系统中的数据。执行该指令不会将外部Cache中的数据写回主存储器。
2) 回写和作废Cache指令WBINVD WBINVD先擦除内部Cache,并分配一个专用总线周期将外部Cache的内容写回主存,在此后的一个总线周期内将外部Cache刷新(清除数据)。 3) 作废TLB项指令INVLPG 该指令用于使页式管理机构内的高速缓冲器TLB中的某项作废。如果TLB中含有一个存储器操作数映像的有效项,则该TLB项被标记为无效。
4.2.4 Pentium系列处理器增加的指令 Pentium系列处理器的指令集是向上兼容的,它保留了8086,8088,80286,80386和80486微处理器系列的所有指令,因此,所有早期的软件可直接在奔腾机上运行。Pentium处理器指令集中增加了三条专用指令和四条系统控制指令,如表4.11所示。 1.Pentium专用指令 1) 比较并交换指令CMPXCHG8B 指令格式: CMPXCHG8B OPRD1,OPRD2 mem,reg
CMPXCHG8B mem,ECX:EBX ;若EDX:EAX=[mem],则ECX: ;EBX→[mem],ZF=1 该指令由80486的CMPXCHG指令改进而来,它执行64位的比较和交换操阼。执行时将存放在OPRD1(64位存储器)中的目的操作数与累加器EDX:EAX的内容进行比较,如果相等,则ZF=1,并将源操作数OPRD2(规定为EDX:EAX)的内容送入OPRD1;否则ZF=0,并将OPRD1送到相应的累加器。例如: CMPXCHG8B mem,ECX:EBX ;若EDX:EAX=[mem],则ECX: ;EBX→[mem],ZF=1 ;否则[mem]→EDX:EAX且ZF=0
2) CPU标识指令CPUID 指令格式: CPUID 使用该指令可以辨别微机中奔腾处理器的类型和特点。在执行CPUID指令前,EAX寄存器必须设置为0或1,根据EAX中设置值的不同,软件会得到不同的标志信息。
3) 读时间标记计数器指令RDTSC 指令格式: RDTSC 奔腾处理器有一个片内64位计数器,称为时间标记计数器。计数器的值在每个时钟周期都递增,执行RDTSC指令可以读出计数器的值,并送入寄存器EDX:EAX中,EDX保存64位计数器中的高32位,EAX保存低32位。 一些应用软件需要确定某个事件已执行了多少个时钟周期,在执行该事件之前和之后分别读出时钟标志计数器的值,计算两次值的差就可得出时钟周期数。
2.Penfium新增系统控制指令 1) 读/写模式专用寄存器指令RDMSR/WRMSR RDMSR和WRMSR指令使软件可访问模式专用寄存器的内容,这两个模式专用寄存器是机器地址检查寄存器(MCA)和机器类型检查寄存器(MCT)。若要访问MCA,指令执行前需将ECX置为0;而为了访问MCT,需要将ECX置为1。执行指令时在访问的模式专用寄存器与寄存器组EDX:EAX之间进行64位的读/写操作。
2) 恢复系统管理模式指令RSM 奔腾处理器有一种称为系统管理模式(SMM)的操作模式,这种模式主要用于执行系统电源管理功能。外部硬件的中断请求使系统进入SMM模式,执行RSM指令后返回原来的实模式或保护模式。
3) 寄存器与CR4之间的传送命令 指令格式: MOV CR4,reg32 MOV reg32,CR4 该指令实现32位寄存器与CR4间的数据传送。