从内存中的数据设置 x86 部分寄存器(EAX、AX、AH)

Posted

技术标签:

【中文标题】从内存中的数据设置 x86 部分寄存器(EAX、AX、AH)【英文标题】:x86 partial registers (EAX, AX, AH) being set from data in memory 【发布时间】:2016-09-26 01:11:20 【问题描述】:

在汇编编程中我理解:

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

谁能解释一下执行后寄存器的所有值是什么?

【问题讨论】:

相关:Assembly language - Why are characters stored in register as little endian? 【参考方案1】:

请参阅Assembly programming memory Allocating EAX vs Ax, AH, AL,了解 AX、AH 和 AL 作为 EAX 的子集如何重叠。

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

所以mov ax, [esi] 保持 EAX 的前 2 个字节不变,并将低 2 个字节替换为 AX=0x1233。这意味着 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(向 -Infinity 舍入,与有符号整数除法不同)。


另请参阅x86 标签 wiki,了解更多常见问题解答以及文档和指南的链接。

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


顺便说一句,mov esi, ptr2 很傻。 mov esi, offset arrayW 会做同样的事情,而不需要从数据内存中加载指针。

【讨论】:

'mov ah, [esi+1]' 执行后寄存器的值有变化吗?因为它是 WORD 所以 [esi+1] 不指向任何东西对吗? [esi+2] 指向第二个元素? @student001:这是汇编语言。一切都只是字节。他们按那个顺序到达那里并不重要,因为您使用了WORD 1233h,2245h 而不是BYTE 33h,12h, 45h, 22h。 CPU 不知道也不关心指令的任何“含义”,它只是从 [esi+1] 加载 1 个字节。 对不起,我是新手。但我只是想确保我理解。因此,如果我使用 DWORD 12344h = BYTE 44h, 23h, 01h 。是对的吗?还有一个,BYTE 1,2,3,4 = WORD 4321h ? @student001:是的,但是您遗漏了第 4 个字节 (00h)。 DWORD 始终为 4 个字节,并且不依赖于常量的大小。 (它代表双字)。 en.wikipedia.org/wiki/Endianness有一些图片。

以上是关于从内存中的数据设置 x86 部分寄存器(EAX、AX、AH)的主要内容,如果未能解决你的问题,请参考以下文章

在 X86 程序集中访问和移动字节

x86 简单 mov 指令

汇编指令和寄存器

x86 cmp 寄存器和内存 - 中间数据保存在哪里?

x86 AT&T 寻址模式中基址寄存器的省略

以x86汇编语言获取EAX寄存器的第一位