我在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位。
答案 0 :(得分:9)
几乎所有两种模式下可用的指令在两种模式下都具有相同的操作码。
删除说明:
CS
/ DS
/ ES
/ SS
已被删除。 push / pop FS和GS仍然有效(这两个段在长模式下仍然可以具有非零基数)。 mov Sreg, r32
和mov r32, Sreg
仍可用于“neutered”段寄存器,因此您可以使用临时整数注册来模拟推/弹。 CS仍然很重要;远程跳转到另一个代码段可以切换到32位模式,其他代码段仍然需要有效的段描述符。 删除(重新调整用途)编码一些仍然可用的指令:在您的情况下,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位模式(长模式)。这意味着您无法同时运行两者,但可以从一种模式切换到另一种模式。