gpt4 book ai didi

assembly - 为什么 32 位寄存器上的 x86-64 指令会将整个 64 位寄存器的上部清零?

转载 作者:行者123 更新时间:2023-12-03 04:50:32 25 4
gpt4 key购买 nike

x86-64 Tour of Intel Manuals ,我读过

Perhaps the most surprising fact is that an instruction such as MOV EAX, EBX automatically zeroes upper 32 bits of RAX register.

同一来源引用的英特尔文档(《基本架构》手册中的 3.4.1.1 64 位模式下的通用寄存器)告诉我们:

  • 64-bit operands generate a 64-bit result in the destination general-purpose register.
  • 32-bit operands generate a 32-bit result, zero-extended to a 64-bit result in the destination general-purpose register.
  • 8-bit and 16-bit operands generate an 8-bit or 16-bit result. The upper 56 bits or 48 bits (respectively) of the destination general-purpose register are not be modified by the operation. If the result of an 8-bit or 16-bit operation is intended for 64-bit address calculation, explicitly sign-extend the register to the full 64-bits.

在 x86-32 和 x86-64 汇编中,16 位指令如

mov ax, bx

不要表现出这种 eax 的高位字被清零的“奇怪”行为。

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

最佳答案

我不是 AMD,也不是他们的代言人,但我也会以同样的方式做到这一点。因为将上半部分清零不会产生对前一个值的依赖,所以 CPU 必须等待。 register renaming如果不这样做,机制基本上就会被击败。

这样您就可以在 64 位模式下使用 32 位值编写快速代码,而不必一直显式地破坏依赖关系。如果没有这种行为,64 位模式下的每条 32 位指令都必须等待之前发生的事情,即使该高位部分几乎永远不会被使用。 (将 int 设为 64 位会浪费缓存占用空间和内存带宽;x86-64 most efficiently supports 32 and 64-bit operand sizes)

8 位和 16 位操作数大小的行为很奇怪。疯狂的依赖性是现在避免使用 16 位指令的原因之一。 x86-64 继承了 8 位的 8086 和 16 位的 386,并决定让 8 位和 16 位寄存器在 64 位模式下的工作方式与在 32 位模式下的工作方式相同。

<小时/>

另请参阅Why doesn't GCC use partial registers?了解实际 CPU 如何处理 8 位和 16 位部分寄存器的写入(以及随后读取完整寄存器)的实际细节。

关于assembly - 为什么 32 位寄存器上的 x86-64 指令会将整个 64 位寄存器的上部清零?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11177137/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com