x86 32位操作码,x86-x64不同或完全删除

时间:2015-09-30 14:09:09

标签: assembly x86 x86-64 cpu-architecture opcode

我在x86-x64中查找了维基百科的x86向后兼容性,它说:

  

x86-64完全向后兼容16位和32位x86   code.Because因为完整的x86 16位和32位指令集仍然存在   存在于硬件中而没有任何干预仿真   x86可执行文件运行时没有兼容性或性能   惩罚,而现有的应用程序被重新编码采取   处理器设计的新功能的优点可能实现   性能改进。

所以我测试了一些指令,看看有些指令实际上产生完全不同的操作码(而不仅仅是应用前缀),例如:INC / DEC。 看(x86):

  

\ x40 inc eax
  \ x48 dec eax

虽然在x86-x64中组装相同的产品:

  

\ xff \ xc0 inc eax

     

\ xff \ xc8 dec eax

我试图弄清楚其他指令的原因和更多示例,这些指令具有产生不同操作码的相同症状。 我熟悉x86-x64中的push,pop,call,ret,enter和leave不可用32位。

2 个答案:

答案 0 :(得分:9)

几乎所有两种模式下可用的指令在两种模式下都具有相同的操作码。

删除说明

  • 二进制编码的十进制内容,如AAM(乘法后的ASCII调整),用于在保持两个基数为10的数字的寄存器上执行正常的二进制加/子/ mul / div后修复二进制编码的十进制数在每个4位半。无论如何,他们跑得很慢,没有被使用。将数字存储为二进制整数而不是BCD是很普遍的。
  • push / pop CS / DS / ES / SS已被删除。 push / pop FS和GS仍然有效(这两个段在长模式下仍然可以具有非零基数)。 mov Sreg, r32mov r32, Sreg仍可用于“neutered”段寄存器,因此您可以使用临时整数注册来模拟推/弹。 CS仍然很重要;远程跳转到另一个代码段可以切换到32位模式,其他代码段仍然需要有效的段描述符。
  • 其他模糊的片段内容,例如ARPL:调整片段选择器的RPL字段。它实际上只是一个位域钳位和整数寄存器的设置标志指令,所以可以通过内核可能需要它的少数几个其他指令进行仿真。
  • 可能是编译器从未在32位代码中使用的其他一些模糊或特权指令。 (并非编译器发出上述任何一种,没有内在函数或内联asm)。

删除(重新调整用途)编码一些仍然可用的指令:在您的情况下,32位可以使用inc r32单字节操作码(0x40 +寄存器) -数)。 64位模式仅具有inc r/m32编码,其中要递增的寄存器由第2个字节指定。 (在这种情况下,0x4x字节被重新用作REX前缀字节)。

英特尔的insn参考(请点击the x86 tag wiki或中的链接)显示以下for inc

Opcode   Instruction Op/   64-Bit   Compat/
                     En     Mode    Leg mode

FF /0   INC r/m32     M     Valid     Valid     Increment r/m doubleword by 1.
40+ rd  INC r32       O      N.E.     Valid     Increment doubleword register by 1.

N.E。意思是不可编码的。 Op / En列描述了如何编码操作数。

Jan Hubicka的AMD64 ISA overview简要描述了REX前缀的单字节inc / dec操作码的重新利用,默认操作数大小以及立即数据仍为32位。 movabs可用于加载64位立即数,或者从64位绝对地址加载/存储。

AMD's AMD64 manual第2.5.11节重新分配的操作码有一个非常短的表。它只列出:

  • 4x inc/dec r32转为REX前缀
  • 63 ARPL变为MOVSXD(与qword签名扩展为dword,与REX.W = 1一起使用时(表示REX前缀中的W位= 1)。

早期的AMD64和Intel EMT64 CPU在长模式下省略了SAHF/LAHF,但后来使用与32位相同的操作码重新添加了该指令。该表还没有列出已被删除的指令(BCD指令和其他指令),这些指令已被删除,以便为将来可能的扩展腾出空间。

他们可以简化很多事情,并使x86-64成为更好的清洁指令集,为未来的扩展提供更多空间,但与32位的差异意味着更多的解码器晶体管。没有机器指令移动到64位的不同操作码。

多台机器指令通常共享相同的asm助记符,mov是最重载的。有加载,存储,具有立即常量的mov,移动到/来自段寄存器,全部在8位和32位。 (16位是带有操作数大小前缀的32位,对于带有REX前缀的64位是相同的。)有一个用于从64位绝对地址加载RAX的特殊操作码。还有一个特殊的操作码,用于将64位立即数加载到寄存器中。 (AT& T语法称这个movabs,但它仍然只是在英特尔/ NASM中移动)

答案 1 :(得分:5)

该陈述是真实的,但有些误导。 x86-64体系结构向后兼容x86,但32位指令集与64位指令集不兼容。

您可以使用兼容模式在x86-64 CPU上运行x86代码。实际上,由于CPU应该是透明的x86到x86代码,它恰恰相反:当你想运行x86-64代码时,你进入64位模式(长模式)。这意味着您无法同时运行两者,但可以从一种模式切换到另一种模式。