我在Wikipedia中查找了x86-x64中的x86向后兼容性,它说:
x86-64 is fully backwards compatible with 16-bit and 32-bit x86 code.Because the full x86 16-bit and 32-bit instruction sets remain implemented in hardware without any intervening emulation, existing x86 executables run with no compatibility or performance penalties,whereas existing applications that are recoded to take advantage of new features of the processor design may achieve performance improvements.
因此,我已经测试了一些指令,以查看某些指令实际上产生了完全不同的操作码(而不仅仅是应用前缀),例如:INC/DEC。
看着(x86):
\x40 inc eax
\x48 dec eax
并且在x86-x64中组装相同的文件时:
\xff \xc0 inc eax
\xff \xc8 dec eax
我正在尝试找出原因相同的症状并产生不同操作码的其他指令的更多示例。
我对x86-x64中的32位不可用的推,弹出,调用,退出,进入和离开熟悉。
最佳答案
两种模式下几乎所有可用的指令在两种模式下都具有相同的操作码。
删除了说明:
CS
/DS
/ES
/SS
的mov Sreg, r32
和mov r32, Sreg
仍可用于“已中和”的段寄存器,因此您可以使用暂存整数reg来模拟push/pop。 CS仍然很重要;跳到另一个代码段可以切换到32位模式,而其他代码段仍需要有效的段描述符。 删除(重新使用)一些仍然可用的指令的编码:在您的情况下,32位可以使用
inc r32
单字节操作码(0x40 +寄存器号)。 64位模式仅具有inc r/m32
编码,其中要递增的寄存器由第二个字节指定。 (在这种情况下,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节重新分配的操作码的表很短。它仅列出:
变成REX前缀的
4x inc/dec r32
63 ARPL
的MOVSXD
(与REX.W = 1(意味着REX前缀中的W位= 1)一起使用时,将dword扩展为qword)。 早期的AMD64和Intel EMT64 CPU在长模式下省略了
SAHF/LAHF
,但后来用与32位相同的操作码重新添加了该指令。该表也没有列出被完全删除的指令(BCD指令以及其他可能删除的指令),以便为将来的扩展留出空间。他们本可以简化很多事情,并使x86-64成为更好的指令集,为将来的扩展留出更多的空间,但是与32bit的每一个区别都意味着更多的解码器晶体管。没有机器指令移至其他64位操作码。
多个机器指令通常共享相同的asm助记符,
mov
是最重载的指令。有加载,存储,立即数常量移动,段寄存器移入/移出段寄存器,全都在8位和32位中。 (16位是带有操作数大小前缀的32位,与带有REX前缀的64位相同。)还有一个单独的操作码,用于从64位绝对地址加载RAX。还有一个特殊的操作码,用于将64位立即数加载到寄存器中。 (AT&T语法将其称为movabs,但在Intel/NASM中仍然只是mov)
关于assembly - x86在x86-x64中不同或已完全删除的32位操作码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32868293/