你说得对;这是相当模糊的。假设我们谈论的是 Intel 语法,那么您确实经常可以逃脱惩罚not使用尺寸指令。只要汇编器可以自动计算出它,它们就是可选的。例如,在指令中
mov esi, DWORD PTR [rax*4+0x419260]
DWORD PTR 说明符是可选的,其原因正是您所想象的:汇编器可以确定要移动 DWORD 大小的值,因为该值正在移动到 DWORD 大小的寄存器中。
同样,在
mov rsi, QWORD PTR [rax*4+0x419260]
出于完全相同的原因,QWORD PTR 说明符是可选的。
但这并不总是可选的。考虑你的第一个例子:
mov QWORD PTR [rip+0x21b520], 0x1
这里,QWORD PTR 说明符是not选修的。如果没有它,汇编器就不知道您要从该地址开始存储什么大小的值rip+0x21b520
。应该0x1
存储为 BYTE?扩展到一个WORD?一个双字? QWORD?一些汇编程序可能会猜测,但如果没有明确指定您想要的结果,您就无法保证正确的结果。
换句话说,当该值位于register对于操作数,大小说明符是可选的,因为汇编器可以根据寄存器的大小计算出大小。但是,如果您正在处理立即值或内存操作数,则可能需要大小说明符以确保获得所需的结果。
就我个人而言,我更喜欢always当我编写代码时包括大小。虽然多打了几个字符,但它迫使我思考并明确说明我想要什么。如果我搞砸了并且编写了不匹配的代码,那么汇编器就会对我大声尖叫,这已经不止一次地捕获了错误。我还认为将它放在那里可以增强可读性。所以在这里我同意老旧的计时器 https://stackoverflow.com/a/44577271/366904,尽管他的观点似乎有些不受欢迎。
反汇编程序的输出也往往很冗长,包括大小说明符,即使它们是可选的。 Hans Passant 在评论中推测这是为了保持与总是需要这些的老式汇编器的向后兼容性,但我不确定这是真的。这可能是其中的一部分,但根据我的经验,反汇编程序往往在lots不同的方式,我认为这只是为了更容易分析您不熟悉的代码。
请注意,AT&T 语法使用的策略略有不同。它不是将大小写为操作数的前缀,而是在指令助记符中添加后缀:b
对于字节来说,w
对于单词来说,l
对于双字,以及q
对于 qword。因此,前面的三个例子就变成了:
movl 0x419260(,%rax,4), %esi
movq 0x419260(,%rax,4), %rsi
movq $0x1, 0x21b520(%rip)
同样,在前两条指令中,l
and q
前缀是可选的,因为汇编器可以推导出适当的大小。在最后一条指令上,就像英特尔语法一样,前缀是非可选的。因此,AT&T 语法与 Intel 语法相同,只是大小说明符的格式不同。