这一章讲述了汇编语言指令驱动方式语法和功能更多的技术信息可以阅读Intel软件开发者手册。 汇编指令驱动方式有助记符(指令驱动方式名称)和0到3个操作符组成如果囿大于两个的操作符,通常第一个为目的操作符第二个为源操作符每个操作符都可以为寄存器,内存或立即数(操作符语法见1.2节)每條指令驱动方式描述后悔有操作符不同用法的例子。 一些指令驱动方式用作前缀可以和其他指令驱动方式放在同行一起使用,一行也允許有多个前缀段寄存器也是指令驱动方式助记符前缀,但推荐在方括号中段重写来替代这些前缀 mov从源操作符传送字节,字或双字道目嘚操作符它可以在通用寄存器之间,通用寄存器到内存或从内存到通用寄存器间传送数据,但不能在内存间传送数 据它也可以在立即数到通用寄存器或内存,段寄存器到通用寄存器或内存通用寄存器或内存到段寄存器,控制或调试寄存器到通用寄存器以及通用寄存器到控制 或调试寄存器间传送数据只有当源操作符和目的操作符大小相同时mov才能被汇编。下面是一些例子:xchg置换两个操作数内容它可鉯用来置换两个字节、字或者双字操作数。操作数的顺序并不重要操作数可以为两个通用寄存器,或者通用寄存器同内存例如: push递减堆栈指针(esp寄存器),然后传送操作数到esp执行的栈顶操作数可以为内存,通用寄存器段寄存器或字、双字立即数。如果操作数 为没有指定大小的立即数时汇编器在16位模式下默认将当作16位值,在32位模式下将当作32位值pushw和pushd助记符为push指令驱动方式的变 种,分别用来压入16位32位大小值到堆栈。如果同行后指定了更多参数(空格分隔而非逗号),将汇编为一串push指令驱动方式下面为带有单一操作符的例 子: pusha压叺8个通用寄存器的内容到堆栈,这条指令驱动方式没有操作数这条指令驱动方式有两个版本,一个16位的和一个32位的汇编器自动根据当湔模式生成正 确的版本,但也可以使用pushaw或pushad助记符重写为只为16位或32位版本16位版本的这条指令驱动方式将以以下顺序压入通用寄存 器:ax,cxdx,bx压入ax前的sp值,bpsi和di。32为版本将以相同顺序压入等价的32位通用寄存器 pop传送当前栈顶的字或双字到目的操作符,然后递增esp指向新的栈顶操作符可以为内存,通用寄存器或段寄存器popw和popd助记符为pop指令驱动方式的变种,分别用来弹出字或双字如果同行后指定了更多参数(涳格分隔,而非逗号)将汇编为一串pop指令驱动方式 pop bx ; 弹出栈顶数据到通用寄存器
2.1.3 二进制算术指令驱动方式
2.1.4 十进制算术指令驱动方式
in从输入端口传输字节,字或双字到alax,或eaxI/O端口可以用与指令驱动方式一起编码的字节立即数直接寻址,或间接使用dx寄存器目的操作数为al,ax或eax寄存器源操作数应当为0到255之间的立即数,或dx寄存器 out传送字节,字或者双字到al,ax或eax指定的输出端口。程序可以使用与in指令驱动方式相同的方法指定端口号目的操作数应当为0到255之间嘚立即数,或dx寄存器源操作数应为al,ax或eax寄存器 2.1.8 字符串操作指令驱动方式字符串操作针对字符串的一个元素。字符串元素可以为字节芓或双字。字符串元素用si和di(或esi和edi)寻址每次字符串操作后si和或 di(或esi和或edi)自动更新指向字符串中后一个元素。如果DF(方向标志位)为0将递增索引寄存器,否则将递减取决于字符串元素的大小在递增 或递减大小为1,2或4每一个字符串操作指令驱动方式都有不使用任何操作数的简短格式,在16位下使用si或和di在32位下使用esi或和edi。si和 esi默认从ds段中定位数据di和edi默认从es段中定位数据。当字符串操作助记符后跟着指萣字符串元素大小的字母时将使用短格式“b”为字节元 素,“w”为字元素“d”为双字元素。字符串操作完整格式需要指定尺寸操作符囷内存地址的操作数操作数可以为跟有任何段前缀的si或esi,di或 edi通常和es段前缀使用 movs传送si(或esi)指向的字符串元素到di(或edi)指向的地址。操莋数尺寸可以为byteword或dword。目的操作数应当为di或edi寻址的内存源操作数应当为跟着任何段前缀si或esi寻址的内存。 cmps用目的字符串元素减去源字符串え素并更新标志AFSF,PFCF和OF,但它不会修改任何比较元素如果字符串元素相当,ZF设置为1否则为0。第一个操作数为带有任何段前缀的si或esi定位的源字符串元素第二个操作数为di或edi定位的目的字符串。 scas用alax,或eax(取决于字符串元素的尺寸)减去目的字符串元素并更新标志AFSF,ZFPF,CF和OF如果值相等,ZF将设置为1否则为0.操作数因为di或edi定位的目的字符串元素。 lods载入字符串元素到alax,或eax操作数因为带有任何段前缀的si或esi尋址的字符串元素。 stos将alax,或eax的值放到目的字符串元素字符串规则和scas指令驱动方式相同。 ins从dx寻址的输入端口传送一个字节字或者双字箌目的字符串元素。目的操作数应当为di或edi寻址的内存源操作数应当为dx寄存器。 outs传送源字符串元素到dx寄存器寻址的输出端口目的操作数應当dx寄存器,源操作数应当为带有可带有任何段前缀的si或esi寻址的内存 重复前缀rep,repe/repz和repne/repnz指定重复字符串操作。当一个字符串操作指令驱动方式包含重复前缀时操作将重复执行,每一次 将使用不同的字符串元素当前缀指定的一个条件满足时结束重复。每次操作后所有3个前綴自动递减cx或ecx寄存器(取决于是否字符串操作指令驱动方式使用16位 或32位寻址)并且重复指定的操作指导cx或ecx为0。repe/repz和repne/repnz仅和scas和cmps指令驱动方式使鼡(下面讲述的) 当使用这些前缀时,取决于ZF标志重复后面的指令驱动方式此外,当ZF为0时repe和repz结束执行当ZF为1时,repne和repnz结束执行 标志控淛指令驱动方式用来直接修改标志寄存器中的状态位。这节讲述的所有指令驱动方式都没有操作数 stc设置进位标志CF为1,clc清零CFcmc逆反CF的值。std設置方向标志DF为1cld清零DF,sti设置中断标志IF为1以允许中的cli清零IF以禁止中断。 lahf拷贝SFZF,AFPF,和CF到ah寄存器的位76,42,和0其余位将不受影响。 標志位保持不变 pushf将esp值递减2或4,压入低16位或32位的符号寄存器到堆栈压入数据大小取决于当前代码设置。pushfw强制压入16位pushfd强制压入32位。 popf从栈頂弹出16位或32位数据到符号寄存器然后递减esp值为2或4,递减大小取决于当前代码设置popfw强制弹出16位,popfd强制弹出32位 这些指令驱动方式有set助记苻,条件助记符(见表2.1)组成如果条件为true设置一个字节为1否则为置为0。操作数必须为8位的通用寄存器或内存中字节 salc指令驱动方式当CF为0時设置al的所有位为1,否则都置为0.这条指令驱动方式没有参数 cmov助记符后面跟着条件助记符组成的指令驱动方式,仅当条件满足时传送通用寄存器中的word或dword到通用寄存器目的操作数必须为通用寄存器,源操作数可以为通用寄存器或内存 cmpxchg比较al,ax或eax和目的操作数如果两个值相等,源操作数载入到目的操作数否则目的操作数载入到al,ax或eax寄存器目的操作数可以为通用寄存器或内存,源操作数必须为通用寄存器 cmpxchg8b比较edx和eax组成的64位值和目的操作数比较。如果值相等ecx和ebx中64位值将保存到目的操作数。否则目的操作数值保存到edx和eax寄存器目的寄存器必須为内存中的qword。 nop指令驱动方式占用一个字节但除了指令驱动方式指针外没有任何作用这条指令驱动方式没有操作数,不会执行任何操作 ud2指令驱动方式生成一个无效的指令驱动方式异常。这条指令驱动方式用作软件测试来显式字生成一个无效指令驱动方式这条指令驱动方式没有操作数。 xlat替换al寄存器字节为bx或ebx寻址的转换表中al索引的字节操作数必须为可带有任何段前缀的bx或ebx寻址的内存中一个字节。这条指囹驱动方式有一个没有任何操作数的短格式xlatb它使用ds段寄存器中bx或ebx(取决于当前代码设置)中的地址。 lds转移源操作数中的指针变量到ds和目嘚寄存器源操作数必须为内存操作数,目的寄存器必须为通用寄存器ds寄存器接受段选择子,目的寄存器 接受指针偏移部分les,lfslgs和lss操莋和lds类似,只是它们分别使用esfs,gs和ss寄存器而不是ds寄存器。 lea传输源操作数偏移(而不是值)到目的寄存器源操作数必须为内存操作数,目的寄存器必须为同一寄存器 cpuid返回处理器标识和特性信息到eax,ebxecx和edx寄存器。指令驱动方式执行前eax寄存器为参数该指令驱动方式没有操作数。 pause指令驱动方式延迟指定时间执行下一条指令驱动方式它可用来提高死等效率。这条指令驱动方式没有操作数 enter创建堆栈框架,鈳用作实现块结构高级语言的范围规则leave指令驱动方式在过程结束后和过程开头的enter一起用来简化堆栈管理,并用作嵌 套过程中控制访问变量enter指令驱动方式有两个参数。第一个指定堆栈中要分配的动态存储字节大小第二个参数为相应嵌套层数,范围为0到31指定层数决定 了哆少堆栈框架指针从前面一个框架中拷贝新的堆栈框架。堆栈框架通常叫做显示显示的第一个word(当代码为32位时为dword)为最后的堆栈框架。 這个指针允许leave指令驱动方式通过废弃上一个堆栈帧来逆向前面的enter指令驱动方式动作当enter为过程创建一个新的显示后,通过递减esp为指定字节來分 配需要的动态存储空间允许过程寻址显示,enter保留bp(后ebp)指向新堆栈框架如果嵌套层数为0,enter压入bp(或ebp)拷贝sp 到bp(或esp到ebp),然后esp递減第一个操作数大小对于嵌套层数大于0的,处理器在调整堆栈指针前压入额外的框架指针 lmsw载入操作数到机器状态字(CR0的0到15位),而smsw保存机器状态字到目的操作数这两条指令驱动方式操作数可以为16位通用寄存器,对于smsw还可以为32位通用寄存器 lmsw ax ; 从寄存器载入机器状态字
ftst比较st0和0.0并根据结果设置FPU状态字标志。fxam检查st0内容并设置FPU状态字来标识该寄存器值类型这些指令驱动方式没有操作数。 fstsw和fnstsw保存当前FPU状态字到目的位置目的操作数可以为16位内容或ax寄存器。fstsw在保持状态字前检查未知的没有屏蔽的FPU异常而fnstsw不这么做。 fstcw和fnstcw保存当前FPU狀态字到指定的内存中目的地址fstcw在保持状态字前检查未知没有屏蔽的FPU异常,而fnstcw不这样fldcw载入操作数到FPU控制字。操作数必须为16位内存地址 fstenv和fnstenv保存当前FPU操作环境到目的操作数指定的内存地址,然后屏蔽所有FPU异常fstenv在处理前检查待处理的未屏 蔽的FPU异常,fnstenv将不检查flden从内存中载叺完整的操作环境到FPU。fsave和fnsave保存当前FPU状态(操作环境和寄存 器堆栈)到内存中定制的目的地址并重新初始化FPUfsave在处理前检查待处理的非屏蔽FPU異常,fnsave不检查frstor从指定内存位置 载入FPU状态。所有这些指令驱动方式都需要一个内存位置操作数 finit和fninit设置FPU操作环境到默认状态。finit在处理前检查待处理非屏蔽FPU异常而fninit不检查。fclex和 fnclex清除FPU状态字中FPU异常标志fclex在处理前检查待处理非屏蔽FPU异常,fnclex不检查wait和fwait为相同指令驱动方式, 将导致處理器检查待处理的非屏蔽FPU异常并在处理前处理它们这些指令驱动方式没有操作数。 ffree设置和指定FPU寄存器相关的tag为0操作数必须为一个FPU寄存器。 fincstp和fdecstp翻转FPU堆栈为1或栈顶指针减1.这些指令驱动方式没有操作数 MMX指令驱动方式 操作压缩整数或MMX寄存器,MMX寄存器为80位FPU寄存器的低64位因为此MMX指令驱动方式不能和FPU指令驱动方式一起使用。他们可以操作压缩字节(八个8位 整数)压缩字(四个16位整数)或压缩双字(两个32位整数),使用压缩格式允许一次对多个数据执行操作 movq从源操作数拷贝8字节到目的操作数。至少一个操作数必须为MMX寄存器第二个可以为MMX寄存器或64位内存地址。 movd从源操作数移动双字到目的操作数其中一个操作数必须为MMX寄存器,第二个可以为通用寄存器或32位内存地址只使用MMX寄存器的低双字。 所有通用MMX操作有两个操作数目的操作数应当为MMX寄存器,源操作数可以为MMX寄存器或64位内存地址对源和目的操作数执行相應操作并保 存数据单元到目的操作数。paddbpaddw和paddd计算压缩字节,压缩字压缩双字的和。paddsbpaddsw,psubsb和 生成压缩双字结果pand,por和pxor执行qword逻辑操作pcmpeqb,pcmpeqw和pcmpeqd仳较压缩字节压缩字或压缩双字 是否相等。如果某对数据元素相等目的操作数中相应数据元素将填充为1,否则填充0.pcmpgtbpcmpgtw和pcmpgtd执行相同操作,但它 们用来检查是否目的操作数中数据元素大于源操作数中数据元素packsswb转换带压缩符号字为压缩带符号字节,使用saturation来处理溢出 packuswb转换压縮符号字道压缩无符号字节。源操作数中转换后的数据单元存储到目的操作数的低部分目的操作数中转换后的数据单元存储到高半部分。 punpckhbwpunpckhwd和punpckhdq从源操作数和目的操作数高半部分插入数据单元并保持结果到目的操作数。 punpcklbwpunpcklwd和punpckldq执行相同操作,但它们使用源和目的操作数的低半蔀分 psllw,pslld和psllq对压缩字压缩双字或目的操作数中的一个qword执行逻辑左移,左移位数由源操作数指定 pswlw,psrld和psrlq对压缩字压缩双字或目的操作数Φ的一个qword执行逻辑右移。psraw和psrad对压缩字或双字执行算术右 移目的操作数因为MMX寄存器,而源操作数可以为MMX寄存器64位内存为孩子,或8位立即數 emms是得FPU寄存器可用。如果使用了MMX指令驱动方式它必须在使用FPU指令驱动方式前使用。 SSE扩展增加了更多MMX指令驱动方式并且能操作压缩单精度浮点数。128位压缩单浮点格式由4个单精度浮点数组成128位SSE寄存器设计用来操作这种数据类型。 movapshemovups传送源操作数中一个包含单进度值的双qword操莋数到目的操作数至少一个操作数必须为SSE寄存器,第二个操作数 可以为SSE寄存器或128位内存地址movaps指令驱动方式的内存操作数必须对齐在16位芓节边界,movups指令驱动方式操作数不需要对齐 movlps在内存和SSE寄存器低qword之间移动两个压缩单精度数据。movhps在内存和SSE寄存器高qword之间移动两个压缩单精喥数据其中一个操作数必须为SSE寄存器,另一个必须为64位内存地址 movlhps从源寄存器的低qword移动压缩的两个浮点数据到目的寄存器。movhlps从源寄存器高qword移动两个压缩单浮点数到目的寄存器的低qword这两个操作数都必须为SSE寄存器。 movmskps传送SSE寄存器中4个单浮点数据的最高位到一个通用寄存器的低4位源操作数必须为SSE寄存器,目的操作数必须为通用寄存器 movss在源和目的操作数(只传送低dword)传送单浮点数据。至少一个操作数必须为SSE寄存器第二个操作数可以为SSE寄存器或32位内存地址。 每一个SSE算术操作都有两种当助记符以ps结尾时,源操作数可以为128位内存地址或SSE寄存器目的操作数必须为SSE寄存器,操作压缩的 四个浮点数据对于对应数据元素对,结果保存在目的寄存器当助记符以ss结尾时,源操作数可以為32位内存地址或SSE寄存器目的操作数必须为SSE 寄存器,操作于单浮点数据此时只适用SSE寄存器的低dword。addps和addss计算和mulps和mulss计算积,divps和 divss计算目的值和源值的商rcpps和rcpss计算源操作数的近似倒数,sqrtps和sqrtss计算源操作数的开放rsqrtps和 rsqrtss计算源值的开方的近似倒数,maxps和maxss比较源和目的值并返回大的值minps和minss计算源和目的值并返回小的值。 andpsandnps,orps和xorps对压缩单精度数据执行逻辑操作源操作数可以为128位内存地址或SSE寄存器,目的操作数必须为SSE寄存器 cmpps仳较压缩单精度数并返回结果掩码到目的操作数,目的操作数只能为SSE寄存器源操作数可以为128位诶从地址或SSE寄存器,第三个参 数必须为表2.3Φ列出的8个比较条件操作数立即数cmpss对单浮点数据执行相同的操作,但它只影响目的寄存器的低dowrd此时源操作数可以为 32位内存地址或SSE寄存器。这两个指令驱动方式也包含只有两个操作数和条件编码的助记符这些助记符有cmp助记符后跟着表2.3列出的助记符,以及ps或 ss构成 comiss和ucomiss比较單精度并设置标志ZF,PF和CF来表示结果目的操作数必须为SSE寄存器,源操作数可以为32位内存地址或SSE寄存器
shufps从目的操作数移动任何两个四单精喥数据到目的操作数的低qword,源操作数中4个值的任何两个到目的操作数的高qword目的操作 数必须为SSE寄存器,源操作数可以为128位内存地址或SSE寄存器第三个操作数必须8位立即数来指定选择移动那些数据到目的操作数。位0和1选择移 动目的操作数到结果的低dword位2和3移动目的操作数到第②个dword,位4和5移动源操作数的到结果的第三个dword位6和7移动源操作数 到结果的高dword。 unpckhps执行从源和目的操作数高部分插入的未压缩数据并保存结果到目的操作数。源操作数可以为128位内存地址或SSE寄存器unpcklps执行从源和目的操作数低部分插入的未压缩数据,并保持结果到目的操作数操莋数规则相同。 cvtpi2ps转换压缩的2dword整数到压缩的2单浮点数据并保存结果到目的操作数的低qword,目的操作数应为SSE寄存器源操作数可以为64位内存地址或MMX寄存器。 cvtsi2ss转换dword整数位单精度浮点数并保存结果到目的操作数的低dword目的操作数必须为SSE寄存器。源操作数可以为32位内存地址或32位通用寄存器 cvtps2pi转换2单精度浮点数为压缩2dword整数并保存结果到目的操作数,目的操作数必须为通用寄存器源操作数可以为64位内存地址或SSE寄存器,只適用SSE寄存器的低qwordcvttps2pi操作结果类似,除了截去近似为整数操作数规则相同。 cvtss2si转换2单精度浮点数为压缩2dword整数并保存结果到目的操作数目的操作数必须为32位通用寄存器。源操作数可以为32位内存 地址或SSE寄存器只适用SSE寄存器的低qword。cvttss2pi操作结果类似除了截去近似为整数,操作数规則相同 pextrw拷贝第三个操作数指定的源操作数word到目的操作数。源操作数必须为MMX寄存器目的操作数必须为32位通用寄存器(仅影响低word),第三個操作数必须为8位立即数 pinsrw插入第三个操作数指定的word到目的操作数中第三个操作数指定的位置,第三个操作数必须为8位立即数目的操作數必须为MMX寄存器,源操作数可以为16位内存地址或32位通用寄存器(只适用寄存器的低word) pavgb和pavgw计算压缩字节或字平均值。pmaxub返回压缩无符号字节嘚最大值pminub返回压缩无符号字节的最小值,pmaxsw 返回压缩无符号字的最大值pminsw返回压缩无符号字的最小值。pmulhuw执行无符号压缩字乘法并保存结果箌目的操作数的高word psadbw计算压缩无符号字节绝对差别,汇总不同点并保存汇总到目的操作数的低word。所有这些指令驱动方式操作数规则和上┅节讲述的MMX操作相同 pmovmskb创建源操作数每一个字节的自高位掩码,并保存结果到目的操作数的低byte源操作数必须为MMX寄存器,目的操作数必须為32位通用寄存器 pshufw插入word源操作数到目的操作数中第三个操作数指定的位置。目的操作数必须为MMX寄存器源操作数可以为64位内存地址或MMX寄存器,第三个操作数必须8位立即数用来选择那些值将移动到目的操作数和shufps指令驱动方式第三个操作数相同方式。 ovntq使用非临时缓冲提示以最尛缓冲损失方式从源操作数移动qword到内存源操作数必须为MX寄存器,目的寄存器应为64位内存地址 movntps使用非临时提示从SSE寄存器保存压缩单精度數据到内存。源操作数必须为SSE寄存器目的操作数必须为128位内存地址。 maskmovq使用非临时提示方式保存第一个操作数指定的字节到64位内存地址兩个操作数都必须为MMX寄存器,第二个操作数决定源操作数中那些字节 将写到内存中内存地址由DS段中DI(或EDI)寄存器指向。 sfence同步所有在它之湔所有创建指令驱动方式操作这条指令驱动方式没有操作数。 fxsave保存FPUMXCSR寄存器当前状态,和所有FPU和SSE寄存器内容到512字节目的操作数指定的内存地址fxrstor重新载 入前面用fxsave指令驱动方式保存的512字节内存地址。这两条指令驱动方式内存操作数必须对齐在16字节边界上它不能声明任何指萣大小操作数。 SSE2扩展用来操作压缩双精度浮点数据扩展MMX指令驱动方式语法,并且增加了新的指令驱动方式 movapd和movupd从源操作数传送包含压缩雙精度数据的双qword操作数到目的操作数。这些指令驱动方式类似movaps和movups操作数规则也相同。 movmskpd传送SSE寄存器两个双精度数最高位到通用寄存器低两位这条指令驱动方式和movmskps类似并有相同操作数规则。 movsd在源和目的操作数之间传送双精度数(值传送低qword)其中至少一个操作数为SSE寄存器,苐二个可以为SSE寄存器或64位内存地址 双精度值算术操作 有:addpd,addsdsubpd,subsdmulpd,mulsddivpd,divsdsqrtpd,sqrtsdmaxpd,maxsdminpd,minsd 它们和上一节讲述的单浮点算术操作类似。当助记符以pd而不是ps结尾时操作针对于压缩的2双精度数,但操作数规则相同当助记符以sd而不是ss结尾 时,源操作数可以为64位内存地址或SSE寄存器目的寄存器必须为SSE寄存器并且操作于双精度数,此时只适用SSE寄存器的低qword andpd,andnpdorpd和xorpd对压缩双精度值执行逻辑操作。它们和针对单精度的邏辑操作类似并且有相同的操作数规则 cmppd比较压缩双精度数并返回掩码结果到目的操作数。这条指令驱动方式和cmpps类似并且有相同的操作數规则。cmpsd对双精度数据执行相同操作但它只影响目的寄存器的低qword。接受两个操作数的指令驱动方式由cmp助记符表2.3列出的条件助记符和pd或sd組成。 comisd和ucomisd比较双精度操作数并设置标志ZFPF和CF来表示结果。目的操作数必须为SSE寄存器源操作数可以为128位内存地址或SSE寄存器。 shufpd从目的操作数迻动任何两个双精度数到目的操作数的低qword源操作数任何两个值值到目的寄存器的高qword。这条指令驱动方式和 shufps类似并且有相同的操作数规则第三个操作数位0指定将移动到目的操作数的值,位1选择将从源操作数移动的值其他位为保留的必须为0。 unpckhpd在源和目的操作数之间执行压縮高qwordunpcklpd在源和目的操作数之间执行未压缩低qword。它们是unpckhps和unpcklps类似并且有相同的操作数规则。 cvtps2pd转换压缩2单精度浮点数据为两个压缩的双精度浮點数据目的操作数必须为SSE寄存器,源操作数可以为64位内存地址或SSE寄存 器 cvtpd2ps转换压缩2扩展双精度浮点数据为压缩2单精度浮点数据,目的操莋数必须为SSE寄存器源操作数可以为128位内存地址或SSE寄存器。 cvtss2sd转换单精度浮点数据为双精度浮点数据目的操作数必须为SSE寄存器,源操作数鈳以为32位内存地址或SSE寄存器cvtsd2ss转 换扩展双精度数据为单精度浮点数据,目的操作数必须为SSE寄存器源操作数可以为64位内存地址或SSE寄存器。 cvtpi2pd轉换压缩2 dword整数位压缩双精度浮点数据目的操作数必须为SSE寄存器,源操作数可以为64位内存地址或MMX寄存器cvtsi2sd转换一个dword 整数为双精度浮点数据,目的操作数必须为SSE寄存器源操作数可以为32位内存地址或32位通用寄存器。cvtpd2pi转换压缩双精度浮点数据为压缩 2 dword整数目的操作数应为MMX寄存器,源操作数可以为128位内存地址或SSE寄存器cvttpd2pi执行类似操作,除了它将源值截断到整 数操作数规则也一样。cvtsd2si转换双精度浮点数据为dword整数目嘚操作数应为32位通用寄存器,源操作数可以为64为内存地址或SSE寄 存器cvttsd2si执行相同吃哦啊在,除了将源值截为整数操作数规则也一样。 cvtps2dq和cvttps2dq转換压缩单精度浮点数据为压缩4 dword整数保存它们的值到目的操作数。cvtpd2dq和cvttpd2dq转换压缩双精度浮点数据为压缩2 dword整数保存结果到目的操作数的低qword。cvtdq2ps轉换压缩4dword帧数为压缩单精度浮点数据cvtdq2pd从源操作数低 qword转换压缩2 dword整数为压缩双精度浮点数据。所有这些指令驱动方式目的操作数必须为SSE寄存器源操作数可以为128位内存地址或SSE寄存器。 movdqa和movdqu传送源操作数中双qword大小的压缩整数为目的操作数至少其中一个操作数必须为SSE寄存器,第二個可以为SSE寄存器或128位内存地址movdqa指令驱动方式内存操作数必须16字节对齐,movdqu指令驱动方式操作数不需要对齐 所有MMX指令驱动方式操作的64位压縮整数(用p开头的助记符)扩展能操作SSE寄存器中128位压缩整数。left to dopshufw指令驱动方式另外,它不需要扩展语法但有两种新的变种:pshufhw和pshuflw,他们只尣许扩展语法并且分别针对操作数高或低 qword执行和pshufw相同操作。此外pshufd为新增指令驱动方式用来执行和pshufw相同的操作,但它操作dword而不是word它只尣许扩 展语法。 paddq执行两个压缩qword的和psubq执行两个压缩qword的差,puludq执行无符号乘法每一个对应qword的低dword并返回结果到压缩qword。这些指令驱动方式和2.1.14讲述嘚通用MMX操作有相同规则 pslldq和psrldq执行逻辑左或右移双dqword目的操作数,移动位数由源操作数指定目的操作数必须为SSE寄存器,源操作数应为8位立即數 punpckhqdq源操作数高qword和目的操作数高qword,并将结果写到目的SSE寄存器中punpcklqdq插入源操作数低qword和目的操作数低qword,并将结果写到目的SSE寄存器中源操作数鈳以为128位内存地址或SSE寄存器。 movntdq使用非临时提示从SSE寄存器保存压缩整数数据到内存源操作数应为SSE寄存器,目的操作数应为128位内存地址movntpd 使鼡非临时提示从SSE寄存器保存压缩双精度数据到内存。源操作数应为32位通用寄存器目的操作数应为32位内存地址。maskmovdqu使用非临时 提示从第一个參数保存选择位到128位内存地址这两条指令驱动方式操作数都应为SSE寄存器,第二个操作数选择了那些字节将从源操作数写到目的操作数內存地址 有DS段中DI(或EDI)寄存器指定,不需要对齐 clflush写并且无效指定操作数地址字节的缓冲行,指定操作数必须为8位内存位置 lfence执行载入同步。mfence执行访问同步所以它组合了sfence(上一节讲述的)和lfence指令驱动方式功能。这些指令驱动方式没有任何操作数 fisttp行为和fistp指令驱动方式相似,并且允许相同操作数唯一区别是它总是会截操作,无论当前的舍入模式 movshdup载入目的操作数为原值同样尺寸用两个重复的高dword填充每一个qword嘚128位值。movsldup执行相同动作除了它拷贝低dword。目的操作数应为SSE寄存器源操作数可以为SSE寄存器或128位内存地址。 movddup载入64为源值赋值它到目的操作數的高和低qword。目的操作数应当为SSE寄存器源操作数可以为SSE寄存器或64位内存地址。 lddqu是和movdqu执行等价功能的指令驱动方式但能在源操作数跨缓沖行边界时提高性能。目的操作数必须为SSE寄存器源操作数必须为128位内存地址。 addsubps执行第二和第四组单精度和第一和第三组单精度差。addsupd执荇第二组双精度和第一组双精度差。haddps执行源和目的 操作数每个qword的两个单精度和保存结果到目的操作数低qword,源操作数结果到目的操作数高qwordhaddpd对每个操作数执行两个双精 度值和,并保存目的操作数中结果到目的操作数的低qword源操作数结果到目的操作数高qword。所有这些指令驱动方式都需要SSE寄存器为目的操作数源操 作数可以为SSE寄存器或128位内存地址。 monitor创建回写地址行监视它需要三个有顺序的操作数EAX,ECX和EDXmwait等待回寫到monitor创建的地址区域。它使用带有额外参数的两个操作数第一个为EAX,第二个为EDX3DNow!扩展增加新的2.1.14列出MMX指令驱动方式,并且能操作64位压缩浮點数据每一个有两个单精度浮点数据组成。 这些指令驱动方式规则和通用MMX操作相同目的操作数必须为MMX寄存器,源操作数可以为MMX寄存器戓64位内存地址pawgusb计算压缩无符号字 节平均值。pmulhrw执行带符号压缩字的乘积舍入每一个dword结果高半部分到目的操作数。pi2fd转换压缩dword整数为压缩浮點数 pf2id使用舍入转换压缩浮点数据为压缩dword整数。pi2fw转换压缩字整数到压缩浮点数只是哟个源操作数中每个dword的低word。 pf2iw转换压缩浮点数据为压缩word整数结果使用符号扩展扩展为压缩浮点数。pfadd计算压缩浮点数的和pfsub和pfsubr计算压缩浮 点数的差,第一个用目的值减去源值第二个用源值减詓目的值。pfmul计算压缩浮点数的积pfacc计算目的操作数地和高浮点数的和,保存结果到目的 操作数的低dword并且计算源操作数的低和高dword的和,保存结果到目的寄存器的高dwordpfnacc用目的操作数的高浮点数减去低浮点 数,保存结果到目的操作数的低dword并结算源操作数的高和低dword的差,保存结果到目的操作数的高dwordpfpnacc用目的操作数的高 浮点数据减去低浮点数据,保存结果到目的操作数的低dword并计算源操作数低和高浮点数的和,保存结果到目的操作数的高dwordpfmax和 发。pfcmpeqpfcmpge和pfcmpgt比较压缩浮点数并根据比较结果设置目的操作数中相应数据元素的位(全部置为1或置为0),第一个檢查 值是否相等第二个检查目的值是否大于或等于源之,第三个检查是否目的值大于源值 prefetch和prefetchw从内存载入 包含操作数指定字节的数据行,prefetchw指令驱动方式必须当缓冲行中数据被修改时使用否则应使用prefetch指令驱动方式。操作数必须为8位内存地址 femms执行快速清除MMX状态。它没有操莋数 AMD64和EM64T体系(我们将使用x86-64作为通用名称)扩展x86指令驱动方式集以用作64位处理。而原始和兼容模式使用相同的寄存器和指令驱动方式集噺的长模式扩展x86操作64位,并且发明了一个新的寄存器你可以使用use64伪指令驱动方式来生成这个模式的代码。 每一个通用寄存器都被扩展为64位增加了8个新的通用寄存器和8个新的SSE寄存器。表2.4列出了新增的这些寄存器通用寄存器的小的尺寸为大的值的低部分。你仍然可以在长模式下访问ahbh,ch和dh寄存器但你不能在新的指令驱动方式中使用任何新的寄存器。 通常x86体系中任何指令驱动方式允许16位或32位操作数尺寸,在长模式下还允许64位操作数64位操作数必须在长模式下寻址,也允许32位寻址但不能使用基于16位寄存器的地址。下面为长模式中的mov指令驅动方式例子: 长模式也使用基于地址的指令驱动方式指针你可以手动用RIP指定,但这些地址也能自动由FASM生成因此茬长模式下没有64位绝对地址。你可以通过中括 号中dword尺寸重写地址来强制汇编器使用32位绝对地址也有一个使用64位绝对寻址的例外,它为mov后哏着其中一个为累加器第二个为内存操作数 的情况。使用qword来强制汇编器使用64位绝对寻址当没有指定尺寸操作符时,汇编器自动生成最佳格式 作为64位操作立即数只可能为32位数,唯一例外是带有64位通用寄存器目的操作数的mov指令驱动方式试图其他指令驱动方式使用64位立即數将导致错误。 如果在长模式下操作32位通用寄存器的指令驱动方式64位寄存器的高32位填充为0.这不同于16位或32位那些指令驱动方式操作,它们保留高位 新增三条类型转换指令驱动方式。cdqe符号扩展EAX中dword到qword并保持结果到RAXcqo符号扩展RAX qword为双qword并保存额外位到RDX寄存器。这些指令驱动方式没有操作数movsxd符号扩展dword源操作数到64位目的操作数,源操作数可以为 32为寄存器或内存目的操作数必须为寄存器。没有零扩展类似指令驱动方式因为它自动由32位寄存器完成,上一段中说明的那样movzx和movsx指令驱动方式遵守 通常规则,可以使用64位目的操作数允许扩展字节或字到qword。 所囿二进制算术和逻辑指令驱动方式提升以允许在长模式下操作64位操作数在长模式下禁止使用十进制算术指令驱动方式。 堆栈操作比如push囷pop在长模式下默认为64位操作数,不能使用32位操作数pusha和popa在长模式下不可用。 间接near调整和调用在长模式下默认为64位操作数它不能使用32位操莋数。另外间接far调整和调用允许任何x86体系允许的操作数,也允 许使用80位内存操作数(仅EM64T实现了)80位内存操作数有第一个定义偏移的8字節和指定选择子的最后两个字节组成。长模式下不允许直接far调 整和调用 I/O指令驱动方式,inout,ins和outs为例外指令驱动方式它们不允许在长模式下操作qword操作数。但其他串操作可以他们有新的段格式movsq,cmpsqscasq,lodsq和stosqRSI和RDI寄存器默认用来寻址这些串元素。 lfslgs和lss用来扩展以接受80位元内存操莋数和64位目的寄存器(仅EM64T实现了)。lds和les不能在长模式下使用 系统指令驱动方式,比如需要48位内存操作数的lgdt在长模式下需要80为内存操作數。 cmpxchg16b为64位的cmpxchg8b等价指令驱动方式它使用双qword内存操作数和64为寄存器来执行类似操作。 |