为什么x64指令将32位寄存器的上半部分清零?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (126)

今天我了解了x64程序集(资料来源:http://x86asm.net/articles/x86-64-tour-of-intel-manuals/

在同一来源中引用的英特尔文档(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
提问于
用户回答回答于

我不是AMD或为他们说话,但我会以同样的方式做到这一点。因为调零高半并不会创建对先前值的依赖关系,所以cpu将不得不等待。如果没有这样做,寄存器重命名机制基本上会被击败。通过这种方式,你可以在64位模式下编写快速的32位代码,而不必一直明确地破坏依赖关系。如果没有这种行为,64位模式下的每一个32位指令将不得不等待之前发生的事情,即使这个高位部分几乎不会被使用。

用户回答回答于

它只是简化了指令和指令集中的空间。你可以使用现有的(32位)指令将小的立即值移动到64位寄存器。

它还可以让你不必编码8个字节的值MOV RAX, 42MOV EAX, 42以便重用。

这种优化对于8位和16位操作系统来说并不重要(因为它们更小),并且在那里更改规则也会破坏旧代码。

扫码关注云+社区

领取腾讯云代金券