问题描述
在汇编 (att) 中,以下内容是合法的:
In assembly (att) the following is legal:
mov %rax, %rbx
等于:
movq %rax, %rbx
其中 q 表示 第一个参数 是 64 位,我的问题是:
Where q means the first parameter is 64 bits, my question is:
这个 q(或其他结尾)是否仅用于人类阅读的简单性,或者在某些情况下,不写 q 会给出错误答案或与预期不同的结果,甚至导致代码崩溃(非法命令),请如果可能的话,给我一个例子.
Is this q (or other endings) used only for simplicity of human reading or there could be some cases where no writing q would give wrong answer or different result than the expected one or even crash the code (illegal command), please give me an example if possible.
推荐答案
您在询问操作数大小后缀.有两种情况:
You're asking about the operand size suffix. There are two cases:
对于许多指令,操作数的大小可以从操作数本身推断出来,通常是因为它们是特定大小的寄存器.这就像您的示例:
mov %rax, %rbx
必须具有 64 位操作数大小,因为%rax, %rbx
是 64 位寄存器.在这种情况下,后缀是可选的,无论你写mov %rax, %rbx
还是movq % 都会生成相同的机器码(
.无论您是否选择包含它,这纯粹是一种风格问题(尽管人们对哪种方式更好有自己的看法).48 89 c3
)rax,%rbx
For many instructions, the operand size can be inferred from the operands themselves, typically because they are registers of a particular size. This is like your example:
mov %rax, %rbx
must have a 64-bit operand size, because%rax, %rbx
are 64-bit registers. In this case, the suffix is optional, and the same machine code (48 89 c3
) is generated whether you writemov %rax, %rbx
ormovq %rax, %rbx
. It's purely a matter of style whether you choose to include it or not (though certainly people have opinions about which way is better).
如果您提供的后缀与操作数不一致,例如movl %rax, %rbx
,汇编器会给出警告或错误.
If you provide a suffix that is inconsistent with the operands, e.g. movl %rax, %rbx
, the assembler will give a warning or error.
在其他情况下,无法推断操作数大小.最常见的情况是当一个操作数是立即数而另一个是内存引用时.如果您从注释中为 ecm 的示例编写 mov $1, (%rbx)
,这是模棱两可的:汇编程序是否应该发出一条指令来存储一个字节(机器码 c6 03 01
),或者一个字(两个字节,66 c7 03 01 00
),或者一个 long(四个字节,c7 03 01 00 00 00
),或者一个四元组(八个字节,48 c7 03 01 00 00 00
)?所以在这种情况下需要一个后缀:你必须写 movb $1, (%rbx)
或 movw $1, (%rbx)
等等.
In others, the operand size cannot be inferred. The most common case is when one operand is an immediate and the other is a memory reference. If you write mov $1, (%rbx)
for ecm's example from comments, it is ambiguous: should the assembler emit an instruction to store a byte (machine code c6 03 01
), or a word (two bytes, 66 c7 03 01 00
), or a long (four bytes, c7 03 01 00 00 00
), or a quad (eight bytes, 48 c7 03 01 00 00 00
)? So a suffix is required in this case: you must write movb $1, (%rbx)
or movw $1, (%rbx)
and so on.
如果你在这种情况下省略后缀,最近的汇编版本至少应该警告你.有些会因为错误而中止;其他人可能会猜测操作数的大小或使用一些内置的默认值,正如彼得在下面评论的那样.一些较旧的汇编器版本实际上会在没有警告的情况下恢复为默认值.
If you omit the suffix in such a case, recent assembler versions should at least warn you. Some will then abort with an error; others may guess at the operand size or use some built-in default, as Peter comments below. Some older assembler versions would actually revert to a default without warning.
所以原则上,是的,省略后缀可能会导致错误"代码,在某些情况下和一些汇编程序.但是,广泛使用的 AT&T 语法汇编器的当前版本至少会警告您.
So in principle, yes, omitting the suffix could lead to "wrong" code, in some cases and with some assemblers. However, current versions of the widely used AT&T-syntax assemblers would at least warn you.
然而,还有另一种可能发生这种情况:假设您想将 5 添加到 32 位寄存器 eax
(addl $5, %eax
),但你打错了,省略了 e
.如果你有使用后缀的习惯,你会写 addl $5, %ax
并得到一个汇编错误,提醒你你的错误.如果您的风格是省略它们,您可以编写 add $5, %ax
并且代码可以完美构建但会错误".
There is however one other way that this can sort of happen: suppose you want to add 5 to the 32-bit register eax
(addl $5, %eax
), but you make a typo and leave off the e
. If you are in the habit of using the suffixes, you would write addl $5, %ax
and get an assembly error, alerting you to your mistake. If your style is to omit them, you would write add $5, %ax
and the code would build perfectly but would be "wrong".
这篇关于大会我们需要结局吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!