现代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
(jmp far
只有0xff的编码是有效的),daa
,das
,aaa
,aas
,aam
,aad
,bound
很少使用),pusha
/ popa
(对附加寄存器salc
没用),(未记录),lahf
并且sahf
不可用.而这基本上就是全部!
不,虽然存在大量重叠,但64位汇编代码不是32位汇编代码的超集,因此32位汇编在64位模式下通常无效.
这适用于助记符汇编源(由汇编程序组装成二进制格式),以及二进制机器代码格式本身.
此问题详细介绍了已删除的说明,但也有许多编码形式的含义已更改.
例如,注释中的Jester给出了push eax
在64位代码中无效的示例.根据此参考,您可以看到32位推送标记为NE,意味着无法编码.在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的答案中找到,这是你应该阅读的答案.
归档时间: |
|
查看次数: |
530 次 |
最近记录: |