Has*_*aza 5 assembly masm x86-16
我目前正在使用 MASM 在 DOSBox 上进行汇编编程(16 位)。
var1 dd 'abcd'
Run Code Online (Sandbox Code Playgroud)
对于上述代码,MASM 生成错误:
A2010:语法错误
语法有什么问题?我只是将 4 个字符存储在一个双字中。
我正在做 16 位汇编,所以这是一个问题吗?我可以只使用dbanddw因为其他变量都大于 16 位吗?
var1 db 'abcd'(not dd) 将您想要的 4 个字节按源顺序放入内存中。
使用 db 以外的变量的目的是什么?
编写初始化程序dd 1234h很方便,比db 34h, 12h, 0, 0将相同的数据组装到输出文件中更方便。此外,当您使用符号时,MASM 将它们视为暗示操作数大小的方式。
更高版本的 MASM 确实接受dd 'abcd',但它们的字节序翻转。(而不是像 NASM 那样按源顺序将字节组装到内存中。)有关 MASM 详细信息,请参阅@RossRidge 的答案。
NASM 会接受mov eax, 'abcd'或者dd 'abcd'很好:多字符文字只是整数文字的另一种形式,第一个字节首先在内存中(最低有效位),因为 x86 是小端字节序。即在 NASM 中,多字符整数文字的内存顺序与其源顺序相匹配。
但 MASM 在与dd或一起使用时会反转它们dw,因此第一个字符成为整数的最高有效字节,并且内存顺序与源顺序相反。即使在支持语法的 MASM 版本中也避免使用它可能是一个好主意,并使用十六进制 ASCII 代码加注释。
在 MASM 中,如果将其声明为变量而不是标签,则var1 ddvs.还会设置用于访问数据的默认操作数大小。db
使用意味着您在任何时候想要使用 访问所有 4 个字节时都var1 db ...必须使用显式。如果没有,MASM 将抱怨操作数大小不匹配。dword ptrmov eax, [var1]dword ptr [var1]
但是,如果您将其声明为只是一个普通标签,而不与任何将字节组装到内存中的 db 或 dd 指令绑定,我认为您可以自由地使用任何大小的它。
(更新:显然,带有 a 的标签:是 MASM 中代码部分之外的错误。我不确定是否有办法声明一个不是 MASM“变量”的数据标签。请参阅评论中的讨论。)
;; I'm not sure this is correct, I'm making this up from memory
;; and I've never actually used MASM. I know the syntax from SO answers.
.data
label1: ; "Just" a label, no data
db 'abcd'
; little-endian 'abcd'
var2 dd 64636261h ; no : so the symbol becomes a variable with a size from the dd
.code
func:
mov eax, [label1] ; legal I think
mov al, [label1] ; also legal
mov eax, dword ptr [label1] ; always works
movzx eax, byte ptr [label1+2] ; zero extend the 'c' into EAX
inc [label1] ; ERROR: ambiguous operand-size
mov eax, [var1] ; fine, both operands are dwords
mov al, [var1] ; ERROR: operand-size mismatch
mov al, byte ptr [var1] ; load the low byte of the dword
inc [var1] ; legal: the "variable" implies dword operand size
inc dword ptr [var1] ; same as above
and byte ptr [var1], ~20h ; upper-case just the first character, 'abcd' into 'Abcd'
Run Code Online (Sandbox Code Playgroud)
请注意,这mov eax, var1相当于mov eax, [var1]MASM 语法,但我更喜欢使用[].