第3章 IA-32指令系统 3.1 基本数据类型 3.2 IA-32的指令格式 3.3 IA-32指令的操作数寻址方式 3.1 基本数据类型 3.2 IA-32的指令格式 3.3 IA-32指令的操作数寻址方式 3.4 IA-32的通用指令 退出
3.1 基本数据类型 IA-32结构的基本数据类型是字节、字、双字、四字和双四字,如图3-1所示。
一个字节是8位,一个字是两个字节(16位),双字是4字节(32位),四字是8字节(64位),双四字是16字节(128位)。 3.1.1 字、双字、四字和双四字的对齐 字、双字和四字在内存中并不需要对齐至自然边界(字、双字和四字的自然边界是偶数编号的地址,对于双字和四字来说,地址要分别能被4和8整除)。 然而,为改进程序的性能,数据结构(特别是堆栈)只要可能应对齐在自然边界上。这样做的理由是:对于不对齐的存储访问,处理器要求做两次存储访问操作;而对于对齐的访问只要做一次存储访问操作。
3.1.2 数字数据类型 1.整数 IA-32结构定义两种类型整数:无符号整数和符号整数。无符号整数是原始二进制值,范围从0到所选择的操作数尺寸能编码的最大正数。符号整数是2的补码二进制值,能用于表示正的和负的整数值。 (1)无符号整数 无符号整数是包含字节、字、双字和四字中的无符号的二进制数。它们的值的范围,对于字节是从0到255;对于字,从0到65535;对于双字,从0到232–1;对于四字,从0到264–1。
(2)符号整数 符号整数是保存在字节、字、双字或四字中的带符号的二进制数。对于符号整数的所有操作都假定用2的补码表示。 整数值的范围,对于字节,从–128到+127;对于字从–32 768到+32 767;对于双字,从–231到+231–1;对于四字,从–263到+263–1。 2.浮点数据类型 IA-32结构定义和操作三种浮点数据类型:单精度浮点、双精度浮点和双扩展的精度浮点。 这些数据类型的数据格式与IEEE标准754二进制浮点算术所规定的格式直接相对应。
3.1.3 指针数据类型 指针是内存单元的地址(见图3-4)。IA-32结构定义两种类型的指针:近(Near)指针(32位)和远(Far)指针(48位)。Near指针是段内的32位偏移量(也称为有效地址)。Near指针在平面存储模式中用于所有存储器引用;或在分段存储模式中用于同一段内的存储器引用。Far指针是一个48位的逻辑地址,包含16位段选择子和32位的偏移。Far指针用于在分段存储模式中的跨段存储引用。
3.1.4 位字段数据类型 一位字段是连续的位序列。它能在内存中任何字节的任一位位置开始,并能包含多至32位。 3.1.5 串数据类型 串是位、字节、字或双字的连续序列。位串能从任一字节的任一位开始并能包含多至232–1位。字节串能包含字节、字或双字,其范围能从0至232–1字节(4G字节)。
3.2 IA-32的指令格式 指令有以下格式: label(标号):mnemonic(助记符)argument1(参数1),argument2(参数2),argument3(参数3) 其中: 标号(label)是一标识符后面跟有冒号(∶)。 助记符(mnemonic)是一类具有相同功能的指令操作码的保留名。
操作数参数1(argument1)、参数2(argument2)和参数3(argument3)是任选的。可以有零至三个操作数,取决于操作码。若存在,它们可能是文字或数据项的标识符、操作数标识符,或者是寄存器的保留名,或者是在程序的另一部分中声明的赋予数据项的标识符。
3.3 IA-32指令的操作数寻址方式 3.3.1 立即数 某些指令用包含在指令中的数据作为源操作数。这些操作数称为立即操作数(或简单称为立即数)。
3.3.2 寄存器操作数 源和目的操作数能在寄存器中。 3.3.3 存储器操作数 在内存中的源和目的操作数由段选择子和偏移量引用。 1.规定段选择子 段选择子能隐含或显式规定。规定段选择子的最简单的方法是把它加载至段寄存器,然后允许处理器根据正在执行的操作类型,隐含地选择寄存器。
2.规定偏移量 内存地址的偏移量部分或者直接作为一个静态值(称为位移量)规定或者由以下一个或多个成员通过计算得到地址: 位移量——一个8位、16位或32位值。 基地址——在通用寄存器中的值。 索引——在通用寄存器中的值。 比例系数——值2、4或8,用于与索引值相乘。 由这些成员相加的结果称为有效地址。这些成员中,除比例系数外其它的每一个都能为正或负(2的补码)。图3-9显示了这些成员能组合成在所选择的段中的有效地址的所有可能的方法。
3.3.4 I/O端口寻址 处理器支持多至包含65536个8位I/O端口的I/O地址空间。在I/O地址空间中也可以定义16位和32位的端口。I/O端口可以用立即操作数或在DX寄存器中的值寻址。用立即数寻址,只能用8位立即数,可寻址I/O地址空间的前256个端口;用DX寄存器间接寻址,可寻址全部I/O地址空间。
3.4 IA-32的通用指令 3.4.1 数据传送指令 数据传送指令在内存和通用寄存器和段寄存器之间传送数据。它们也执行特殊的操作,例如条件传送、堆栈访问和数据转换。
1.MOV指令 MOV指令是最常用的数据传送指令。它的格式是: MOV DOPD,SOPD 它有两个操作数,左边的是目标操作数(DOPD),右边的是源操作数(SOPD)。它把8位、16位或32位源操作数传送至目的地。它在通用寄存器之间、存储器和通用寄存器或段寄存器之间传送数据,或把立即数传送至通用寄存器。
2.条件传送指令 CMOVcc DOPD,SOPD 这是由Pentium PRO(即第六代处理器结构)引入的条件传送指令。在传送前,先检查由EFLAGS的状态位(主要是进位标志CF、符号标志SF、零标志ZF和溢出标志OF)构成的条件是否符合指定的条件,若符合指定的条件,则源操作数(SOPD)传送至目标操作数(DOPD);否则,目标操作数不变。
3.交换指令 (1)XCHG指令 XCHG DOPD,SOPD 这是一条交换指令,它有两个操作数:DOPD和SOPD,指令的功能是使两个操作数交换。这条指令的操作数可以是一个字节或一个字。 (2)BSWAP指令 这是一条字节对换指令。它的格式为: BSWAP DOPD 它只有一个操作数,它使32位(目标)寄存器的字节顺序反向,即使位0到7与位24到31对换,位8到15与位16到23对换。此指令用于小数在前的值与大数在前的值相互转换。
(3)XADD交换并相加指令 指令的格式为: XADD DOPD,SOPD 它用第二个操作数(源操作数)与第一个操作数(目的操作数)交换,然后把两个值的和装入目的操作数。目的操作数可以是寄存器或内存单元,源操作数是一寄存器。
(4)CMPXCHG 比较和交换指令 指令的格式为: CMPXCHG DOPD,SOPD 此指令有两个操作数,它把累加器AL、AX或EAX寄存器的值(取决于操作数的尺寸)与目标操作数相比较。若两值相等,则把源操作数(SOPD)的值加载至目标操作数(DOPD);否则,目标操作数加载至累加器(AL、AX或EAX)。
(5)CMPXCHG8B比较和交换8字节指令 此指令的格式为: CMPXCHG8B DOPD(64位内存操作数) 此指令把64位在内存中的目标操作数与EDX:EAX中的64位值相比较,若相等,则把包含在ECX:EBX中的64位值存储至目标操作数;否则,把目标操作数中的值存入EDX:EAX寄存器对。目标操作数是8字节的内存单元。对于EDX:EAX和ECX:EBX寄存器对,EDX和ECX包含64位值的高32位,而EAX和EBX包含64位值的低32位。
4.堆栈操作指令 (1)入栈指令 PUSH DOPD 操作数的长度为字或双字,在入栈操作时,把一个字(或双字)从源操作数传送至由SP(ESP)所指向的堆栈的顶部。 每一个指令分两步执行: 先SP-1→SP,然后把AH(寄存器中的高位字节)送至SP所指的单元;再次使SP-1→SP,把AL(寄存器中的低位字节)送至SP所指的单元。
(2)出栈指令 POP DOPD 把现行SP所指向的堆栈顶部的一个字(或双字),送至指定的目的操作数;同时进行修改堆栈指针的操作,即SP+2→SP。 (3)PUSHA/PUSHAD 推入通用寄存器至堆栈 PUSHA(Push All)推入所有的16位(即8086)的通用寄存器至堆栈。 PUSHAD(Push All Double)推入所有32位的通用寄存器至堆栈。
(4)POPA/POPAD自堆栈弹出至通用寄存器 POPA(Pop All)自堆栈弹出至16位通用寄存器。 POPAD(Pop All Double)自堆栈弹出至32位通用寄存器。 5.输入输出指令 (1)IN 输入指令。允许把一个字节或一个字由一个输入端口(port),传送至AL(若是一个字节)、AX(若是一个字)或EAX(双字)。 (2)OUT 输出指令。允许把在AL中的一个字节、在AX中的一个字或在EAX中的一个双字,传送至一个输出端口。
6.扩展指令 (1)CWD/CDQ CWD能把在AX中的字的符号扩展至DX中(形成32位操作数)。若AX<8000,则0→DX;否则FFFFH→DX。 CDQ把在EAX中的双字的符号扩展送至EDX中(形成64位操作数)。若EAX<80000000H,则0→EDX;否则,FFFFFFFFH→EDX。
(2)CBW/CWDE CBW把在寄存器AL中的字节的符号送至AH中(形成16位操作数)。若AL<80H,则扩展后0→AH;若AL>=80H,则扩展以后FFH→AH。 CWDE把在寄存器AX中的字的符号送至EAX的高16位中(形成32位操作数)。若AX<8000H,则把0→EAX的高16位;否则,把FFFFH送至EAX的高16位。
(3)MOVSX传送并符号扩展。 此指令的格式为: MOVSX DOPD,SOPD 其中,目标操作数DOPD是寄存器操作数(某一通用寄存器)。源操作数SOPD可以是寄存器或内存操作数,源操作数可以是字节或字。此指令是把一字节源操作数按符号扩展为字或双字传送至目标寄存器中;或把字操作数按符号扩展为双字传送至目标寄存器中。
(4)MOVZX传送且零扩展 此指令的格式为: MOVZX DOPD,SOPD 其中,目标操作数DOPD是寄存器操作数(某一通用寄存器)。源操作数SOPD可以是寄存器或内存操作数,源操作数可以是字节或字。此指令是把一字节源操作数按零扩展为字或双字传送至目标寄存器中;或把字操作数按零扩展为双字传送至目标寄存器中。
3.4.2 二进制算术指令 1.加法指令 (1)ADD DOPD,SOPD 这条指令完成两个操作数相加,结果送至目标操作数,即DOPD←DOPD+SOPD 目的操作数可以是累加器、任一通用寄存器以及存储器。 (2)ADC(Add with Carry) 此指令的格式为: ADC DOPD,SOPD 这条指令与上一条类似,只是在两个操作数相加时,要把进位标志C的现行值加上去,结果送至一个目标操作数(DOPD)。
2.减法指令 (1)SUB指令 此指令的格式为: SUB DOPD,SOPD 这条指令完成两个操作数相减,也即从DOPD中减去SOPD,结果放在DOPD中。具体地说,可以从累加器中减去立即数;或从寄存器或内存操作数中减去立即数;或从寄存器中减去寄存器或内存操作数;或从寄存器或内存操作数中减去寄存器操作数等。 (2)SBB(Subtract with Borrow)指令此指令的格式为: SBB DOPD,SOPD 这条指令与SUB指令类似,只是在两个操作数相减时,还要减去借位标志CF的现行值。
3.乘法指令 (1)MUL无符号数乘法指令 此指令的格式为: MUL SOPD 本指令完成在AL(字节)或AX(字)中的操作数以及另一个操作数(两个无符号数)的乘法。双倍长度的乘积,送回到AL和AH(在两个8位数相乘时),或送回到AX和它的扩展部分DX(在两个字操作数相乘时)。 (2)IMUL符号数乘法指令 整数乘法指令。这条指令除了是完成两个带符号数相乘以外,其它与MUL完全类似。
4.除法指令 (1)DIV 这条无符号数的除法指令,能把在AX和它的扩展部分(若是字节相除则在AH和AL中,若是字相除则在DX:AX中)中的无符号被除数被源操作数除,且把相除以后的商送至累加器(8位时送至AL,16位时送至AX),余数送至累加器的扩展部分(8位时送至AH,16位时送至DX)。 (2)IDIV(Integer division) 这条指令除了完成带符号数相除以外,与DIV完全类似。
5.增量减量指令 (1)INC增量 这条指令完成对指定的操作数加1,然后返回此操作数。 (2)DEC减量 本指令对指定的操作数减1,然后把结果送回操作数。 6.NEG取补指令 这条指令是对操作数取补,也即用零减去操作数,再把结果送回操作数。 7.CMP比较指令 比较指令完成两个操作数相减,使结果反映在标志位上,但两操作数不变。
3.4.3 十进制算术指令 1.DAA(Decimal Adjust for Addition)在加法后进行十进制调整 这条指令能对在AL中的由两个组合的十进制数相加的结果,进行校正,以得到正确的组合的十进制和。 2.DAS(Decimal Adjust for Subtraction)在减法后进行十进制调整 本指令与DAA指令类似,能对在AL中的由两个组合的十进制数相减以后的结果,进行校正,以得到正确组合的十进制差。
3.AAA(Unpacked BCD[ASCll] Adjust for Addition)在加法后进行ASCII调整 这条指令对在AL中的由两个未组合的十进制操作数相加后的结果进行校正,产生一个未组合的十进制和。 4.AAS(Unpacked BCD[ASCII] Adjust for Subtraction)在减法后进行ASCII调整 本指令与AAA指令类似、能把在AL中的由两个未组合的十进制数相减的结果,进行校正,在AL中产生一个正确的未组合的十进制数差。
5.AAM(Unpacked BCD[ASCII] Adjust for Multiply)在乘法后进行ASCII调整 这条指令能把在AX中的两个未组合的十进制数相乘的结果,进行校正,最后在AX中能得到正确的未组合的十进制数的乘积(即高位在AX中,低位在AL中)。 6.AAD(Unpacked BCD[ASCII] Adjust for Division)在除法前进行调整 这条指令能把在AX中的两个未组合的十进制数在两个数相除以前进行校正,这样在两个未组合的十进制数相除以后,可以得到正确的未组合的十进制结果。
3.4.4 逻辑指令 1.AND执行按位逻辑与 (1)AND指令 这条指令对两个操作数进行按位的逻辑“与”运算,即只有相“与”的两位全为1,与的结果才为1;否则与的结果为0。“与”以后的结果送至目的操作数。 (2)TEST 本指令完成与AND指令同样的操作,结果反映在标志位上,但并不送回至目标操作数,即TEST指令不改变操作数的值。
2.OR执行按位逻辑或 此指令对指定的两个操作数进行逻辑“或”运算。即进行“或”运算的两位中的任一个为1(或两个都为1),则或的结果为1;否则为0。或运算的结果送回目的操作数。 3.XOR执行按位逻辑异或 这条指令对两个指定的操作数进行“异或”运算,当进行“异或”运算的两位不相同时(即一个为1,另一个为0),“异或”的结果为1;否则为0。异或运算的结果送回一个操作数。 4.NOT执行按位逻辑非 这条指令对源操作数求反,然后送回原操作数。
3.4.5 移位和循环移位指令 1.移位指令 有四条移位指令:SAL(算术左移)、SHL(逻辑左移)、SAR(算术右移)和SHR(逻辑右移)。这些指令的格式为: SAL DOPD,OPD2 SHL DOPD,OPD2 SAR DOPD,OPD2 SHR DOPD,OPD2
第一个操作数是目标操作数,即对它进行移位操作。目标操作数可以是任一通用寄存器或一内存操作数(可用所有寻址方式)。第二个操作数规定移位的次数(或移位的位数)。在8086中,第二个操作数或是1(规定移一位)或为寄存器CL(在寄存器CL中规定移位的次数)。在IA-32处理器中,不仅把目标操作数扩展至32位,而且第二个操作数可以是CL或8位立即数,用于规定移位次数为0至31。
2.双移位指令 (1)SHLD双左移 此指令的格式为: SHLD DOPD,SOPD,OPD3 其中,第一个操作数为目标操作数,它执行左移操作;目标操作数可以为16位或32位通用寄存器或内存操作数(可用所有寻址方式)。第二个操作数为寄存器操作数,其尺寸必须与目标操作数相同。第三个操作数规定移位的次数,可以是8位立即数或寄存器CL,规定移位次数为1至31。 (2)SHRD双右移 除了移位方向相反,此指令与上一指令完全相同。
3.循环移位指令 有四条循环移位指令ROL(Rotate Left)、ROR(Porate Right)、RCL(Rorate through CF Left)和RCR(Rotate through CF Right)。 指令格式为: ROL DOPD,OPD2 其中,第一个操作数是要对其进行移位操作的目标操作数。第二个操作数是8位立即数或寄存器CL,用以规定移位的次数(1至31)。 前两条循环移位指令,未把标志位CF包含在循环的环中。后两条把标志位CF包含在循环的环中,作为整个循环的一部分。
3.4.6 位和字节指令 1.位操作指令 有四条位操作指令: BT位测试 BTS位测试并置位 BTR位测试并复位 BTC位测试并置反 这些指令的格式为: BT DOPD,SOPD 第一个操作数是目标操作数,规定一个位串(称为位基),第二个操作数规定在位串中的偏移(从位0开始算起)。
2.位扫描指令 有两条位扫描指令: BSF向前位扫描 BSR反向位扫描 这些指令的格式为: BSF DOPD,SOPD 源操作数SOPD是16位或32位的寄存器或存储操作数,BSF指令的功能是从源操作数的最低有效性(位0)开始向前扫描,查找第一个为1的位。若找到这样的位把它与最低有效位的偏移值存入目标操作数。目标操作数是16位或32位寄存器。若源操作数为0,则目标操作数的内容不定。
3.条件字节设置指令SETcc 此类指令的格式为: SETcc DOPD 此类指令只有一个操作数——目标操作数,它是一个8位寄存器。若满足指令规定的条件,置目标操作数为1;否则,把它置0。
3.4.7 控制传送指令 1.无条件转移指令JMP转移 这是一条无条件转移指令,它转移程序控制至指令流的不同点而不保留返回信息。目标操作数规定指令要转移到的地址。此操作数可以是立即数、一通用寄存器或一内存单元。 指令的格式为: JMP DOPD
近转移——转移至当前码段(由CS寄存器当前指向的段),有时称为段内转移。 短转移——一种near转移,其转移范围限制在当前EIP的–128到+127之内。 远转移——转移至与当前码段不同的段内的指令,但在相同特权级,有时称为段间转移。 任务切换——转移至不同任务中的指令。
2.条件转移指令Jcc 其一般格式为: Jcc Label 其中,Label是转移的目标地址。即若满足指令中规定的条件,则转移至目标地址;否则继续执行下一条指令。
3.重复控制指令 一个循环程序必须要有指令来控制循环,重复控制指令在循环的头部或尾部确定是否进行循环。是否重复也是有条件的,通常是在CX(ECX)寄存器中预置循环次数,重复控制指令当CX(ECX)不等于零时,循环至目的地址。若不满足条件(通常当CX=0时),则顺序执行重复控制指令的下一条指令。 重复控制指令的目的地址必须在控制指令的+127和-128字节的范围之内。
(1)LOOP LOOP指令使CX(ECX)减1,且判断若CX(ECX)不等于0,则循环至目标操作数——IP+偏移量(符号扩展到16位)。 (2)LOOPZ(或LQOPE) 这同一条指令有两种不同的助记符LOOPZ及LOOPE。 此指令使CX减1,且判断只有在CX不等于0,而且标志ZF=1的条件下,才循环至目标操作数——IP+偏移量。 (3)LOOPNZ(或LOOPNE) 这也是同一条指令的两种助记符。此指令使CX减1,且判断只有当CX不等于0,而且标志ZF=0的条件下,才能循环至目标操作数——IP+偏移量。
4.调用与返回指令 (1)CALL调用过程 CALL指令能执行四种不同类型的调用: Near调用——调用在当前码段(由CS寄存器指向的当前段)内的过程,有时称为段内调用。 Far调用——调用位于与当前代码段不同段中的过程,有时称为段间调用。 不同特权级间的far调用——调用与当前执行的程序或过程有不同特权级的段内的过程。 任务切换——调用位于不同任务中的过程。
(2)RET返回 有两种返回指令: RET RET OPD 传送程序控制至位于堆栈顶部的返回地址。此地址是由CALL指令放在堆栈上的。通常,返回指令返回至CALL指令的下一条指令。
RET指令能用于执行三种不同类型的返回: Near返回—返回至在当前代码段(由CS寄存器当前指向的段)内的调用过程,有时称为段内返回。 Far返回—返回至与当前代码段不在同一段内的调用过程,有时称为段间返回。 特权级间的far返回——返回至与当前执行的程序或过程不同的特权级。 最后一种返回只能在保护模式下执行。返回指令的返回类型,取决于相应的CALL指令。
(3)IRET从中断返回 有两种中断返回指令的形式: IRET IRETD 它从异常或中断处理程序返回程序控制至被异常、外部中断或软件中断所中断的程序或过程。这些指令也用于从嵌套的任务(嵌套的任务是当CALL指令用于启动任务切换,或当中断或异常引起任务切换至中断,或异常处理程序时建立的)返回。
处理器执行以下类型的中断返回: 从虚拟8086模式返回。 返回至虚拟8086模式。 特权级内返回。 特权级间返回。 从嵌套的任务返回(任务切换)。 不论哪种返回方式,IRET指令的功能是一致的。
(4)INT软件中断、INTO在溢出时中断 INT n指令产生由目标操作数规定的中断或异常处理程序的调用。目标操作数n规定从0到255的中断向量号(作为8位无符号数编码)。 INTO指令是调用溢出异常(中断向量号4)特定助记符。溢出中断检测在EFLAGS寄存器中的OF标志,若OF标志为1,则调用溢出中断处理程序,否则,顺序执行下一条指令。
5.过程指令 (1)BOUND检测值是否超出范围 此指令的格式为: BOUND OPD1.OPD2 确定第一个操作数(数组索引)是否在由第二个操作数(边界操作数)规定的数组边界内。若数组索引不在边界之内,则发生边界范围超过异常。
(2)ENTER高级过程进入 此指令的格式为: ENTER OPD1,OPD2 它为过程建立堆栈帧。第一个操作数(尺寸操作数)规定堆栈帧的尺寸(即,为过程分配到堆栈上的动态存储的字节数)。第二个操作数(嵌套层操作数)给定过程的词法嵌套层(0至31)。嵌套层确定从前面帧拷贝至新堆栈帧的“显示区”的堆栈帧指针的数量。这两个操作数都是立即数。
3.4.8 串指令 (1)MOVS(Move String) MOVS/MOVSB 传送串/传送字节串 MOVS/MOVSW 传送串/传送字串 MOVS/MOVSD 传送串/传送双字串 把由SI(ESI)作为指针的源串中的一个字节(MOVSB)、字(MOVSW)或双字(MOVSD),传送至由DI(EDI)作为指针的目的串,且相应地修改指针,以指向串中的下一个元素。
(2)CMPS(Compare String) CMPS/CMPSB比较串/比较字节串 CMPS/CMPSW比较串/比较字串 CMPS/CMPSD比较串/比较双字串 由SI(ESI)作为指针的源串与由DI(EDI)作为指针的目的串(双字、字或字节)相比较(源串-目的串),但减的结果只反映到标志位上,而不送至任何一操作数。同时相应地修改源和目的串指针,指向串中的下一个元素。
(3)SCAS(Scan String) SCAS/SCASB扫描串/扫描字节串 SCAS/SCASW扫描串/扫描字串 SCAS/SCASD扫描串/扫描双字串 搜索串指令,关键字放在AL(字节)、AX(字)或EAX(双字)中,操作时从AL(字节操作)、AX(字操作)或EAX(双字操作)的内容中减去由DI(EDI)作为指针的目的串元素,结果反映在标志位上,但并不改变目的串元素以及累加器中的值。
(4)LODS(Load String) LODS/LODSB装入串/装入字节串 LODS/LODSW装入串/装入字串 LODS/LODSD装入串/装入双字串 本指令把由SI(ESI)作为指针的串元素,传送至AL(字节操作)、AX(字操作)或EAX(双字操作),同时修改SI(ESI),使其指向串中的下一个元素。这个指令正常地是不重复执行的,因为每重复一次,累加器中的内容就要改写,只保留最后一个元素。
(5)STOS(Store String) STOS/STOSB存储串/存储字节串 STOS/STOSW存储串/存储字串 STOS/STOSD存储串/存储双字串 从累加器AL(字节操作)、AX(字操作)或EAX(双字操作)传送一个字节、字或双字,到由DI(EDI)作为指针的目的串中,同时修改DI(EDI)以指向串中的下一个单元。利用重复操作,可以在串中建立一串相同的值。
(6)串输入指令INS/INSB/INSW/INSD——从端口输入至串 指令的格式是: INS m8,DX INS m16,DX INS m32,DX INSB INSW INSD
从源操作数(第二个操作数)拷贝数据至目标操作数(第一个操作数)。源操作数是一I/O端口地址(从0至65,535),它通常是由DX寄存器规定。目标操作数是一内存单元,它的地址由ES:DI或ES:EDI(取决于指令的地址属性,分别是16或32)规定(ES段不能用地址超越前缀来超越)。正在访问的I/O端口的尺寸(即源和目标操作数的尺寸),对于8位I/O端口取决于操作码,而对于16位或32位I/O端口取决于指令的操作数属性。在汇编码级,允许两种形式的指令:显式和无操作数式。无操作数形式,隐含着源端口由DX寄存器规定;而目标操作数由ES:(E)DI规定。
(7)串输出指令OUTSB/OUTSW/OUTSD——拷贝串至端口 此类指令的格式为: OUTS DX,m8 OUTS DX,m16 OUTS DX,m32 OUTSB OUTSW OUTSD
此类指令从源操作数(第二个操作数)拷贝数据至由目标操作数(第一个操作数)规定的I/O端口。源操作数是一内存单元,其地址由DS:DI或DS:EDI寄存器(取决于指令的地址尺寸属性,分别是16或32)(DS段可以用段前超越)。目标操作数是一I/O端口地址(从0至65535),由DX寄存器规定。
3.4.9 标志控制操作 标志控制指令对在EFLAGS寄存器中的标志进行操作。 3.4.10 段寄存器指令 此类指令从源操作数(第二个操作数)加载一far指针[段选择子和偏移量至指定的段寄存器和第一个操作数(目标操作数)]。源操作数在内存中规定48位或32位指针取决于操作数尺寸属性(分别是32位或16位)。指令操作码和目标操作数规定段寄存器/通用寄存器对。16位段选择子从源操作数加载至用操作码规定的段寄存器(DS、ES、SS、FS或GS)。32位或16位偏移量加载至由目标操作数规定的寄存器。
3.4.11 杂项指令 (1)LEA加载有效地址 此指令的格式为: LEA r16,m LEA r32,m 计算源操作数的有效地址(即段内偏移量)并存储至目标操作数。源操作数是一内存单元(可用各种寻址方式);目标操作数是一通用寄存器。地址尺寸(取决于代码段的属性)和操作数尺寸属性(取决于所选的寄存器)影响此指令执行的动作。
(2)NOP空操作 (3)UD2未定义的指令 (4)XLAT/XLATB表格查找传送 用AL寄存器作为表的索引,定位在内存中的字节项,然后把它送至AL。在AL寄存器中的索引作为无符号数对待。 (5)CPUID处理器标识