为什么在x86汇编中操作数必须在一行中具有大小而在另一行中没有 [英] Why operand must have size in one line but not the other in x86 assembly

查看:56
本文介绍了为什么在x86汇编中操作数必须在一行中具有大小而在另一行中没有的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看图片,在第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 for 0FFH. 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屋!

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