我对x86寄存器的理解是,每个寄存器都可以被整个32位代码访问,并且它被分成多个可访问的寄存器。
在这个例子中EAX
作为一个 32 位寄存器,如果我们调用AX
它应该返回前 16 位,如果我们调用AH
or AL
它应该返回 16 位之后的接下来的 8 位,并且AL
应返回最后 8 位。
所以我的问题是,因为我并不真正相信这就是它的运作方式。如果我们存储 32 位值EAX
存储:
0000 0100 0000 1000 0110 0000 0000 0111
所以如果我们访问AX
它应该返回
0000 0100 0000 1000
如果我们读AH
它应该返回
0000 0100
当我们阅读时AL
它应该返回
0000 0111
它是否正确?如果这就是价值的作用AH
真正持有吗?
不,这不太正确。
EAX
是完整的 32 位值
AX
是低 16 位
AL
是低8位
-
AH
是位 8 到 15(从零开始),AX 的上半部分
因此 AX 由 AH:AL 两半组成,并且本身是 EAX 的低半部分。 (EAX 的上半部分不能作为 16 位寄存器直接访问;如果您想访问它,可以移位或旋转 EAX。)
x86-64 CPU 将整数寄存器扩展到 64 位:
-
RAX
是完整的 64 位值,EAX 及其子组件映射到低 32 位。 64 位寄存器的上半部分只能在 64 位模式下访问,这与 32 位寄存器不同,32 位寄存器可以在支持它们的 CPU 上以任何模式使用。
所有这些也适用于 EBX/RBX、ECX/RCX 和 EDX/RDX。其他寄存器如 EDI/RDI 有一个 DI 低 16 位部分寄存器,但没有高 8 部分,并且低 8 DIL 只能在 64 位模式下访问:64 位架构中的汇编寄存器
写入 AL、AH 或 AX 会使完整 AX/EAX/RAX 中的其他字节保持不变,由于历史原因。例如,它必须将新的 AL 合并到完整的 RAX 中。 (在 32 位或 64 位代码中,更喜欢movzx eax, byte [mem]
or movzx eax, word [mem]
如果您不特别想要此合并,请加载:为什么 GCC 不使用部分寄存器?)
将 EAX 零扩展写入 RAX. (为什么 32 位寄存器上的 x86-64 指令会将整个 64 位寄存器的上部清零?)
再次强调,所有这些都适用于每个寄存器,而不仅仅是 RAX。例如写入 DI 或 DIL 会合并到旧的 RDI 中,写入 EDI 会进行零扩展并覆盖完整的 RDI。对于 R10B 或 R10W 写入合并也是如此,写入 R10D 使 R10 独立于旧的 R10 值。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)