所有x86 32位汇编代码是否都有效x86 64位汇编代码?
我想知道32位汇编代码是否是64位汇编代码的子集,即每个32位汇编代码是否可以在64位环境中运行?
我想答案是肯定的,因为64位Windows能够执行32位程序,但后来我发现64位处理器支持32位兼容模式?
如果没有,请提供一个32位汇编代码的小例子,该代码不是有效的64位汇编代码,并解释了64位处理器如何执行32位汇编代码。
答案 0 :(得分:7)
现代x86 CPU有三种主要的操作模式(简化了这种描述):
现在16位,32位和64位模式有什么区别?
16位和32位模式基本相同,只是存在以下差异:
现在,64位模式有所不同。大多数指令的行为与32位模式类似,但有以下区别:
inc
和dec
指令不可用,其指令空间已重新用于REX前缀。双字节inc
和dec
仍然可用,因此仍可以对inc reg
和dec reg
进行编码。fs
和gs
覆盖(0x64,0x65)之外,段覆盖不可用。push/pop seg
(push/pop fs/gs
除外),arpl
,call far
(只有0xff编码有效),les
,lds
,{ {1}}(只有0xff编码有效),jmp far
,daa
,das
,aaa
,aas
,aam
,aad
(很少使用),bound
/ pusha
(对附加寄存器无用),popa
(未记录), salc
和lahf
不可用。基本上就是这一切!
答案 1 :(得分:5)
不,虽然存在大量重叠,但64位汇编代码不是32位汇编代码的超集,因此32位汇编在64位模式下通常无效。
这适用于助记符程序集 source (由汇编程序组装成二进制格式),以及二进制机器代码格式本身。
This question涵盖了已删除的一些详细说明,但也有许多编码形式的含义已更改。
例如,注释中的Jester给出了push eax
在64位代码中无效的示例。基于this reference,您可以看到32位推送标记为 N.E。,意味着不可编码。在64位模式下,编码用于表示push rax
(8字节推送)。因此,相同的字节序列在32位模式与64位模式下具有不同的含义。
通常,您可以浏览该站点上的指令列表,并找到许多列为64位无效或无法编码的内容。
如果没有,请提供一个32位汇编代码的小例子 是无效的64位汇编代码并解释64位处理器如何 执行32位汇编代码。
如上所述,push eax
就是这样一个例子。我认为缺少的是64位CPU支持直接运行32位二进制文件。它们不是通过机器语言级别的32位和64位指令之间的兼容性来实现的,而只是通过具有 32位模式,其中解码器(特别是)解释指令流作为32位x86而不是x86-64,以及用于运行64位指令的所谓长模式。当这样的64位芯片首次发布时,通常运行一个32位操作系统,这意味着芯片永远处于这种模式(永远不会进入64位模式)。
最近,通常运行一个64位操作系统,它知道模式,当用户启动32位进程时,它会使CPU进入32位模式(这仍然是非常的常见的是:直到最近我的浏览器仍然是32位。
模式的所有细节和正确术语都可以在fuz的答案中找到,这是你应该阅读的答案。