为了账号安全,请及时绑定邮箱和手机立即绑定

为什么在32位寄存器上的x86-64指令为全64位寄存器的上部为零?

/ 猿问

为什么在32位寄存器上的x86-64指令为全64位寄存器的上部为零?

慕慕森 2019-06-03 17:22:40

为什么在32位寄存器上的x86-64指令为全64位寄存器的上部为零?

x8664英特尔手册之旅,我读到

也许最令人惊讶的事实是,像这样的指令MOV EAX, EBX的上32位自动为零。RAX登记。

同一来源引用的Intel文档(3.4.1.1在手动基本架构中采用64位模式的通用寄存器)告诉我们:

  • 64位操作数在目标通用寄存器中生成64位结果.
  • 32位操作数在目标通用寄存器中生成32位结果,零扩展到64位结果.
  • 8位和16位操作数产生8位或16位结果.目的通用寄存器的上56位或48位(分别)不被操作修改。如果8位或16位操作的结果用于64位地址计算,则显式地将寄存器扩展到64位。

在x86-32和x86-64程序集中,16位指令如

mov ax, bx

不要表现出这种“奇怪”的行为,即eax的上端单词是零的。

因此:引入这种行为的原因是什么?乍一看,这似乎不合逻辑(但原因可能是我已经习惯了x86-32程序集的怪癖)。


查看完整描述

2 回答

?
慕标5265247

我不是AMD,也不是他们的代言人,但我会用同样的方式去做。因为对上半部分进行零化并不会造成对前一个值的依赖,所以CPU必须等待。如果没有这样做,注册重命名机制将基本上失败。这样,您就可以在64位模式下编写快速32位代码,而不必始终显式地中断依赖关系。如果没有这种行为,64位模式下的每一个32位指令都必须等待以前发生的事情,尽管这个高部分几乎不会被使用。

16位指令的行为是奇怪的。依赖疯狂是现在避免16位指令的原因之一。


查看完整回答
反对 回复 2019-06-03
?
RISEBY

它只需在指令和指令集中节省空间。您可以使用现有(32位)指令将小的即时值移动到64位寄存器中。

它还使您不必对8字节值进行编码。MOV RAX, 42,何时MOV EAX, 42可以重复使用。

这种优化对于8位和16位操作(因为它们更小)不那么重要,而更改规则也会破坏旧代码。


查看完整回答
反对 回复 2019-06-03
  • 2 回答
  • 0 关注
  • 220 浏览
我要回答
慕课专栏
更多

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信