gpt4 book ai didi

linux - 确定 NASM 何时可以推断出 mov 操作的大小

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:51:47 26 4
gpt4 key购买 nike

有一段时间让我对 x86 汇编感到困惑,NASM 如何/何时可以推断操作的大小,这是一个例子:

mov ebx, [eax]

这里我们将存储在 eax 中的地址中的 4 个字节移动到 ebx 中。由于寄存器是 32 位,因此推断操作的大小为 4 个字节。

但是,此操作不会被推断并引发编译错误:

mov [eax], 123456

当然解决方案是这样的:

mov dword [eax], 123456

这会将数字 123456 的 32 表示形式移动到存储在 eax 中的地址中的字节中。

但这让我感到困惑,它肯定可以看到 eax 是 32 位的,所以它不应该假设我想将它存储为 32 位值而无需在 mov 之后指定 dword 吗?

当然,如果我想将 12345 的 16 位表示(较小的数字适合 16 位)放入 eax,我会这样做:

mov ax, 12345

最佳答案

对于任何具有内存目标和直接源的指令,操作数大小是不明确的(因此必须指定)。 (即使在寻址模式下使用一个或多个,操作数实际上也不是寄存器。)

地址大小和操作数大小是指令的独立属性。


引用您在对另一个答案的评论中所说的话,因为我认为这是您困惑的核心:

I would expect mov [eax], 1 to set the 4 bytes held in memory address eax to the 32 bit representation of 1

BYTE/WORD/DWORD [PTR]注解与内存地址的大小无关;它是关于该地址处内存中变量的大小。假设平面 32 位寻址,地址 总是四个字节长,因此必须放在 Exx 寄存器中。因此,当源操作数是立即数时,目标操作数上的双字(或其他)注释是汇编程序知道它是否应该修改 1、2 或 4 字节 RAM 的唯一方法。

如果我演示这些注释对机器代码的影响,也许它会有所帮助:

$ objdump -d -Mintel test.o
...
0: c6 00 01 mov BYTE PTR [eax], 0x1
3: 66 c7 00 01 00 mov WORD PTR [eax], 0x1
8: c7 00 01 00 00 00 mov DWORD PTR [eax], 0x1

(与 objdump 实际打印它的方式相比,我稍微调整了间距。)

请注意两件事:(1) 三个不同的操作数前缀会产生三个不同的机器指令,(2) 使用不同的前缀会更改发送到机器代码中的源操作数的长度。

关于linux - 确定 NASM 何时可以推断出 mov 操作的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30959266/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com