x86部分寄存器(EAX,AX,AH)是根据内存中的数据设置的

时间:2016-09-26 01:11:20

标签: assembly x86 masm

在汇编编程中,我理解:

EAX : 22 66 77 55
 AX :       77 55
 AH :       77
 AL :          55

但是当我从具有指针偏移的数组中读取数据时,我真的不明白它是如何工作的:

 .data 
 arrayW WORD 1233h,2245h, 1176h

 ptr2 PWORD arrayW

 .code 
    mov esi, ptr2
    mov ax, [esi]
    mov ah, [esi + 1]
    mov ax, [esi + 2]
    mov eax, [esi + 2]

mov ax,[esi] 寄存器EAX = 12331233.我认为寄存器EAX是00001233?

另外, mov ax,[esi + 2] 寄存器= EAX = 12334455.我不明白寄存器是如何变成12334455的。

有人可以向我解释执行后寄存器的所有值是什么吗?

1 个答案:

答案 0 :(得分:4)

有关AX,AH和AL如何重叠的信息,请参阅Assembly programming memory Allocating EAX vs Ax, AH, AL作为EAX的子集。

写入部分寄存器(AX,AH或AL)不会修改EAX的其余部分。 (在64位模式下,writing EAX does zero the upper half of RAX

因此mov ax, [esi]保留EAX的前2个字节未修改,并用AX = 0x1233替换低2字节。这意味着AH = 0x12且AL = 0x33,EAX = 0x22 66 12 33

内存中的字节是小端,因此mov ah, [esi + 1]加载0x12(0x1233的高字节,即数组的第一个字。)

这是汇编语言。一切都只是字节。他们按顺序到达那里并不重要,因为您使用的是WORD 1233h,2245h而不是BYTE 33h,12h, 45h, 22h。 CPU不知道或不关心指令的任何“含义”,它只从[esi+1]加载1个字节,并将其放入AH中。 (已经有mov ax, [esi]的价值。

寄存器中的字节没有字节序,因为它们没有地址。左移总是乘以2,右移总是除以2(向无穷大舍入,与有符号整数除法不同)。

另请参阅代码维基以获取更多常见问题解答,以及指向文档和指南的链接。

您始终可以将此代码放入程序中并在调试器中运行,以便在单步执行时更改注册寄存器值。如果您不确定会发生什么,请执行此操作。

BTW,mov esi, ptr2很愚蠢。 mov esi, offset arrayW可以做同样的事情而无需从数据存储器加载指针。