47

我对 x86 寄存器的理解是,每个寄存器都可以被整个 32 位代码访问,并且它被分成多个可访问的寄存器。

在这个例子EAX中是一个 32 位寄存器,如果我们调用AX它应该返回前 16 位,如果我们调用AHorAL它应该返回 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真正具有什么价值?

4

6 回答 6

93

不,这不太对。

EAX is the full 32-bit value
AX is the lower 16-bits
AL is the lower 8 bits
AH is the bits 8 through 15 (zero-based)

所以 AX 由 AH:AL 两半组成,它本身就是 EAX 的低半部分。(EAX 的上半部分不能作为 16 位寄存器直接访问;如果你想得到它,你可以移位或旋转 EAX。)

为了完整起见,除了上述基于 32 位 CPU 的内容外,64 位 Intel/AMD CPU 还具有

RAX, which hold a 64-bit value, and where EAX is mapped to the lower 32 bits.

所有这些也适用于 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 位代码中,如果您不特别想要这种合并,请首选 amovzx eax, byte [mem]或load:为什么 GCC 不使用部分寄存器?movzx eax, word [mem]

将 EAX 零扩展写入 RAX。(为什么 32 位寄存器上的 x86-64 指令将整个 64 位寄存器的上半部分归零?

同样,所有这些都适用于每个寄存器,而不仅仅是 RAX。例如,写入 DI 或 DIL 会合并到旧 RDI,写入 EDI 零扩展并覆盖整个 RDI。对于 R10B 或 R10W 写入合并相同,写入 R10D 使 R10 独立于旧的 R10 值。

于 2013-03-03T21:37:23.360 回答
44

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
于 2013-03-03T21:38:10.130 回答
37
| 0000 0001 0010 0011 0100 0101 0110 0111 | ------> EAX

|                     0100 0101 0110 0111 | ------> AX

|                               0110 0111 | ------> AL

|                     0100 0101           | ------> AH
于 2018-10-19T12:50:03.797 回答
7

不,你的答案是错误的

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  
于 2014-04-26T11:12:43.727 回答
4

否——AL 是 AX 的 8 个最低有效位。AX 是 EAX 的 16 个最低有效位。

如果我们从 eax 中的 04030201h 开始,也许最容易处理。在这种情况下,AX 将包含 0201h,AH 将包含 02h,AL 将包含 01h。

于 2013-03-03T21:37:31.150 回答
4

下面的代码片段使用 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
  1. EAX - 完整的 32 位值
  2. AX - 低 16 位值
  3. AH - 8 到 15 位
  4. AL - EAX/AX 的低 8 位
于 2015-11-28T03:40:59.403 回答