提问人:Randy 提问时间:3/4/2013 最后编辑:CommunityRandy 更新时间:10/21/2023 访问量:170438
AX、AH、AL 如何映射到 EAX?
How do AX, AH, AL map onto EAX?
问:
我对 x86 寄存器的理解是,每个寄存器都可以被整个 32 位代码访问,并且它被分解成多个可访问的寄存器。
在这个例子中,作为一个 32 位寄存器,如果我们调用它,它应该返回前 16 位,如果我们调用 or,它应该返回 16 位之后的下一个 8 位,并且应该返回最后 8 位。EAX
AX
AH
AL
AL
所以我的问题是,因为我并不真正相信这就是它的运作方式。如果我们存储 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 位代码中,如果您不特别想要这种合并,请首选 a 或 load:为什么 GCC 不使用部分寄存器?movzx eax, byte [mem]
movzx eax, word [mem]
)
将 EAX 零扩展到 RAX 中。(为什么 32 位寄存器上的 x86-64 指令将完整 64 位寄存器的上半部分归零?)
同样,所有这些都适用于每个寄存器,而不仅仅是 RAX。例如,写入 DI 或 DIL 合并到旧的 RDI 中,写入 EDI 零扩展并覆盖完整的 RDI。R10B 或 R10W 写入合并相同,写入 R10D,使 R10 独立于旧的 R10 值。
评论
否 -- AL 是 AX 的 8 个最低有效位。AX 是 EAX 的 16 个最低有效位。
如果我们在 eax 中从 04030201h 开始,也许最容易处理。在这种情况下,AX 将包含 0201h,AH 将包含 02h,AL 将包含 01h。
AX 是 EAX 的 16 位较低位。AH 是 AX 的 8 个高位(即 EAX 的 8-15 位),AL 是 EAX 和 AX 的最低有效字节(位 0-7)。
示例(十六进制数字):
EAX: 12 34 56 78
AX: 56 78
AH: 56
AL: 78
不,你的回答是错误的
Al 和 Ah 的选择来自 AX,而不是来自 EAX
例如
EAX=0000 0000 0000 0000 0000 0000 0000 0111
因此,如果我们调用 AX,它应该返回
0000 0000 0000 0111
如果我们调用 AH,它应该返回
0000 0000
当我们调用 AL 时,它应该返回
0000 0111
示例编号 2
EAX: 22 33 55 77
AX: 55 77
AH: 55
AL: 77
示例 3
EAX: 1111 0000 0000 0000 0000 0000 0000 0111
AX= 0000 0000 0000 0111
AH= 0000 0000
AL= 0000 0111
评论
movl $0x01 %eax
%ax
%al
mov $imm32, %eax
opcode 01 00 00 00
1
)
以下代码片段使用 GDB 检查 EAX。
(gdb) info register eax
eax 0xaa55 43605
(gdb) info register ax
ax 0xaa55 -21931
(gdb) info register ah
ah 0xaa -86
(gdb) info register al
al 0x55 85
- EAX - 完整的 32 位值
- AX - 较低的 16 位值
- AH - 从 8 到 15 位
- AL - 较低的 EAX/AX 8 位
评论
p /x $eax
/x
set $eax = 0xdeadbeef
| 0000 0001 0010 0011 0100 0101 0110 0111 | ------> EAX
| 0100 0101 0110 0111 | ------> AX
| 0110 0111 | ------> AL
| 0100 0101 | ------> AH
这是访问寄存器的映射: 然后你可以理解 , , , 寄存器: EAX
AX
AH
AL
| 00000000 11111111 11111111 00000000 | | EAX |
| 11111111 00000000 | | AX |
| 11111111 | | AH |
| 00000000 | | AL |
另一个例子:
| 10110101 11010101 10100110 00001111 | | EAX |
| 10100110 00001111 | | AX |
| 10100110 | | AH |
| 00001111 | | AL |
因为来自 x86 程序集/x86 体系结构:
最低有效字节 (LSB) 或低半部分通过用“L”替换“X”来标识。最高有效字节 (MSB) 或高半部分改用“H”。
评论