确定NASM何时可以推断mov操作的大小 [英] Determining when NASM can infer the size of the mov operation

查看:63
本文介绍了确定NASM何时可以推断mov操作的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有些事情让我在x86汇编中感到困惑,这是NASM如何/何时推断操作的大小,这是一个示例:

Something has got me confused in x86 assembly for a while, it's how/when can NASM infer the size of the operation, here's an example:

mov ebx, [eax]

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

Here we are moving the 4 bytes stored at the address held in eax into ebx. The size of the operation is inferred as 4 bytes because the register is 32 bits.

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

However, this operation doesn't get inferred and throws a compile error:

mov [eax], 123456

当然解决的方法是这样:

Of course the solution is this:

mov dword [eax], 123456

将把数字123456的32个表示形式移动到存储在eax地址处的字节中.

Which will move the 32 representation of the number 123456 into the bytes stored at the address held at eax.

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

But this confuses me, surely it can see eax is 32 bit, so shouldn't it assume I want to store it as a 32 bit value without me having to specify dword after the mov?

当然,如果我要将16345的16位表示形式(较小的数字可容纳16位)放入eax中,我会这样做:

Surely if I wanted to put the 16 bit representation of 12345 (smaller number to fit in 16 bits) into eax I would do this:

mov ax, 12345

推荐答案

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

The operand-size would be ambiguous (and so must be specified) for any instruction with a memory destination and an immediate source. (Neither operand actually being a register, even if using one or more in an addressing mode.)

地址大小和操作数大小是指令的单独属性.

Address-size and operand-size are separate attributes of an instruction.

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

Quoting what you said in a comment on another answer, since I think this gets at the core of your confusion:

我希望 mov [eax],1 将内存地址eax中保存的4个字节设置为1的32位表示形式.

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寄存器中.因此,当源操作数是立即数时,目标操作数上的dword(或任何其他方式)注释是汇编器知道其是否应该修改RAM的1、2或4字节的唯一方法.

The BYTE/WORD/DWORD [PTR] annotation is not about the size of the memory address; it's about the size of the variable in memory at that address. Assuming flat 32-bit addressing, addresses are always four bytes long, and therefore must go in Exx registers. So, when the source operand is an immediate value, the dword (or whatever) annotation on the destination operand is the only way the assembler can know whether it's supposed to modify 1, 2, or 4 bytes of RAM.

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

Perhaps it will help if I demonstrate the effect of these annotations on machine code:

$ 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 实际打印的方式相比,我已经调整了一些间距.)

(I've adjusted the spacing a bit compared to how objdump actually prints it.)

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

Take note of two things: (1) the three different operand prefixes produce three different machine instructions, and (2) using a different prefix changes the length of the source operand as emitted into the machine code.

这篇关于确定NASM何时可以推断mov操作的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆