为什么在x86汇编中操作数必须在一行中具有大小而在另一行中没有 [英] Why operand must have size in one line but not the other in x86 assembly
问题描述
看图片,在第34行,我必须编写 word ptr
才能起作用,而在第44行,我没有写.
这是为什么?
Looking at the picture, on line 34 I had to write the word ptr
for this to work, while on line 44 I didn't.
Why is that?
编译器不知道0020h是一个单词,就像0FF20h是一个单词一样吗?
将0添加到0020h使其变为00020h或类似的方法也不起作用.
Can't the compiler know that 0020h is a word just like 0FF20h is a word?
Adding 0 to 0020h making it 00020h or anything like that doesn't work either.
我在80x86上使用MASM.emu8086,也在dosbox v0.74上尝试过
I am using MASM on 80x86. emu8086, also tried on dosbox v0.74
推荐答案
差异是因为您的汇编器奇怪而危险地接受 0FF20h
表示 word
操作数大小.但是,即使对于您的汇编程序,前导零并不意味着操作数大小,而只是实际值.大概会检查最高有效位的位置.
The difference is because your assembler strangely and dangerously accepts 0FF20h
as implying word
operand-size. But even for your assembler, leading zeros don't imply operand-size, just the actual value; presumably it checks the position of the most significant bit.
像NASM这样的设计良好且一致的汇编程序语法不是这种情况:如果我尝试使用 nasm -fbin foo.asm
This is not the case for a well-designed and consistent assembler syntax like NASM: If I try to assemble this in 16-bit mode with nasm -fbin foo.asm
mov [es: si], 2
mov [es: si], 0ff20H
我得到这些错误:
foo.asm:1: error: operation size not specified
foo.asm:2: error: operation size not specified
只有寄存器可以隐含整个指令的操作数大小,而不是常量的宽度.( mov [si],ax
并不模糊:没有任何形式的 mov
,其中目标的宽度不同于源,而 ax
绝对是 word
大小.)
Only a register can imply an operand-size for the whole instruction, not the width of a constant. (mov [si], ax
is not ambiguous: there is no form of mov
where the destination has a different width than the source, and ax
is definitely word
sized.)
同样适用于AT& T和Intel语法模式下的GAS(GNU汇编器).(它的Intel语法模式与MASM非常相似.)
Same applies for GAS (the GNU assembler), in both AT&T and Intel syntax modes. (Its Intel-syntax mode is very similar to MASM.)
没有 mov r/m16,sign_extended_imm8
编码,但是有 add
和大多数ALU操作,因此没有理由让汇编器假定xyz [mem],0
表示字节操作数大小.程序员更有可能忘记指定,因此将其视为错误,而不是默默地接受含糊不清的内容.
There's no mov r/m16, sign_extended_imm8
encoding, but there is for add
and most ALU operations, so there's no reason for an assembler to assume that xyz [mem], 0
means byte operand size. More likely the programmer forgot to specify, so it treats it as an error instead of silently accepting something ambiguous.
mov word [mem], 0
是一种完全正常的将内存中的单词清零的方法.
mov word [mem], 0
is a totally normal way to zero a word in memory.
除此之外, x86使用 66h
操作数大小前缀以16位代码支持32位操作数大小.这与地址大小无关.
Besides all that, x86 supports 32-bit operand size in 16-bit code, using a 66h
operand-size prefix. This is independent from the address-size.
移动单词ptr es:[si],0FF20h
也是可编码的,并且如果忽略了 mov word ptr es:[si],0FF20h
size ptr
说明符.
mov dword ptr es:[si], 0FF20h
is also encodeable, and completely ambiguous with mov word ptr es:[si], 0FF20h
if you leave out the size ptr
specifier.
正如Jester所说,如果将前导零计为常量宽度的一部分,则很容易将 0FF20h
视为暗含 dword
.
As Jester commented, if leading zeros counted as part of the width of the constant, 0FF20h
could easily be taken as implying dword
.
请注意,您也必须用前导零编写
0FF20H
,因此,如果汇编程序确实依赖于文字的长度,它可能会认为这是一个双字……对于> 0FFH
.这将是一个危险的游戏.请注意,明智的汇编器甚至不允许您在没有显式尺寸的情况下使用第二种形式.那只是一个等待发生的错误.
Note that you had to write
0FF20H
with a leading zero too so if the assembler really relied on the length of the literal, it could have thought that was a dword ... similarly for0FFH
. It would be a dangerous game. Note sensible assemblers don't even allow your second form without explicit size. That's just a bug waiting to happen.
(明智的汇编器包括NASM和GAS,如我上面所示).
(Sensible assemblers include NASM and GAS, like I showed above).
如果我是你,我会很不高兴我的汇编器毫无怨言地接受了 mov es:[si], 0FF20h
.我以为emu8086甚至比MASM还差,并且通常接受 mov [si],2
之类的东西,并带有一些默认操作数大小,而不是警告.
If I were you, I'd be unhappy that my assembler accepted mov es:[si], 0FF20h
without complaint. I thought emu8086 was even worse than MASM, and usually accepted stuff like mov [si], 2
with some default operand size instead of warning even then.
我也不是MASM如何神奇地从 symbol db 1,2,3
推断操作数大小的狂热者,但这并不是模棱两可的,它只是意味着您必须查看如何符号被声明为知道它所隐含的操作数大小.
I'm not a big fan of how MASM magically infers operand-size from symbol db 1, 2, 3
either, but that's not ambiguous, it just means you have to look at how a symbol was declared to know what operand-size it will imply.
这篇关于为什么在x86汇编中操作数必须在一行中具有大小而在另一行中没有的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!