AX、AH、AL 如何映射到 EAX?

How do AX, AH, AL map onto EAX?

提问人:Randy 提问时间:3/4/2013 最后编辑:CommunityRandy 更新时间:10/21/2023 访问量:170438

问:

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

在这个例子中,作为一个 32 位寄存器,如果我们调用它,它应该返回前 16 位,如果我们调用 or,它应该返回 16 位之后的下一个 8 位,并且应该返回最后 8 位。EAXAXAHALAL

所以我的问题是,因为我并不真正相信这就是它的运作方式。如果我们存储 32 位值,也就是存储:EAX

0000 0100 0000 1000 0110 0000 0000 0111

因此,如果我们访问它应该返回AX

0000 0100 0000 1000

如果我们阅读它应该返回AH

0000 0100

当我们阅读时,它应该返回AL

0000 0111

这是正确的吗?如果是这样,真正有价值的是什么?AH

汇编 x86 CPU 寄存器

评论

0赞 Hans Passant 3/4/2013
不,您的 AX 值是错误的。砍掉最后 16 位。AH 仅返回 EAX 的第 8 位到第 15 位。
5赞 Micha Wiedenmann 3/4/2013
请将位模式替换为更易于理解的内容,例如:0000 0001 0010 0011 ...
0赞 Peter Cordes 6/9/2021
相关:汇编语言 - 为什么寄存器中的字符存储为小字节序? 回复:映射到内存。

答:

108赞 500 - Internal Server Error 3/4/2013 #1

不,这不太对。

  • 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 值。

评论

0赞 user97662 6/27/2017
你怎么称呼更高的 16 位和更高的 32 位?有EAXH还是AXH?
1赞 500 - Internal Server Error 6/27/2017
@user97662:不,无法仅访问寄存器的上部 - 您必须读取整个寄存器并根据需要进行移位。
0赞 wintermute 12/4/2017
当我在俄罗斯上学时,我们主要学习DOS中的16位汇编语言。我确实记得通用寄存器遵循小端系统,例如 AX 是 |AL|啊|。尽管我很难将这个概念外推到 32 位寄存器上。这样的事情对EAX来说是合法的吗? |AL|啊|EAL|EAH|还是只是 |AL|啊|EAX公司 | ?
1赞 Peter Cordes 9/30/2022
@wintermute:为什么没有包含更高字节的 EAX 的寄存器? 介绍了原因。在汇编中访问寄存器的高阶字节涵盖了要做什么,特别是注释有一些有效的建议。
4赞 Jerry Coffin 3/4/2013 #2

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

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

44赞 pascalhein 3/4/2013 #3

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
7赞 Electronic Engineer 4/26/2014 #4

不,你的回答是错误的

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  

评论

1赞 Frozen Flame 8/27/2014
和端序有什么关系吗?如果我使用 GAS 进行组装,和的值是什么?一个还是零?movl $0x01 %eax%ax%al
0赞 Peter Cordes 9/19/2017
@FrozenFlame:不,字节序仅适用于内存(包括指令的编码方式,如 .)。%al 中的值将为 。如果您认为寄存器中的 MSB 在左侧,LSB 在右侧,则左移 %eax 有效。(对于矢量寄存器来说,这可能会变得棘手,请参阅 stackoverflow.com/questions/41351087/...mov $imm32, %eaxopcode 01 00 00 001)
4赞 scanjee 11/28/2015 #5

以下代码片段使用 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 位

评论

2赞 Peter Cordes 9/19/2017
您还可以使用 (或省略 for decimal) 打印 GDB 中的寄存器。并用 IIRC 修改它们。另请参阅 x86 标签 wiki 的底部,了解 asm 的一些 gdb 提示。p /x $eax/xset $eax = 0xdeadbeef
47赞 Miku Ghoul 10/19/2018 #6
| 0000 0001 0010 0011 0100 0101 0110 0111 | ------> EAX

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

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

|                     0100 0101           | ------> AH
0赞 winapiadmin 10/21/2023 #7

这是访问寄存器的映射: 然后你可以理解 , , , 寄存器: access registersEAXAXAHAL

| 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”。