问题描述
我目前正在使用MASM在DOSBox上进行汇编编程(16位).
var1 dd'abcd'
对于上面的代码,MASM正在生成错误:
语法有什么问题?我只是在一个双字中存储4个字符.
我正在执行16位汇编,所以有问题吗?因为其他变量大于16位,我只能使用 db
和 dw
吗?
var1 db'abcd'
(不是 dd
)将想要的4个字节放入源代码中的内存中订单.
编写初始化程序的便利性 dd 1234h
比 db 34h,12h,0、0
更方便,但是会将相同的数据组合到输出文件中.同样,当您使用符号时,MASM将它们视为隐含操作数大小的方式.
更高版本的MASM确实接受 dd'abcd'
,但是会按字节顺序对其进行翻转.(而不是像NASM那样按字节顺序将字节组装到内存中.)请参阅.
NASM可以接受 mov eax,'abcd'
或 dd'abcd'
:多字符文字只是整数文字的另一种形式,第一个字节首先在内存中(最低有效),因为x86是小尾数法.也就是说,在NASM中,多字符整数文字的存储顺序与其源顺序相匹配.
但是,当与 dd
或 dw
一起使用时,MASM会将它们反转,因此第一个字符成为整数的 most 有效字节,并占用内存order是源顺序的相反顺序.即使在支持该语法的MASM版本中,也应避免使用它,并使用十六进制ASCII码加上注释.
在MASM中,如果将数据声明为变量而不是标签,则 var1 dd
与 db
还将设置用于访问数据的默认操作数大小./p>
使用 var1 db ...
意味着您每次想通过 mov eax访问所有4个字节时,都必须使用显式的
.如果没有 dword ptr
,[var1] dword ptr [var1]
,MASM将抱怨操作数大小不匹配.
但是,如果您将其声明为纯标签,而不是将字节组合到内存中的任何db或dd指令绑定,则我认为您可以自由使用任意大小的标签.
(更新:显然带有:
的标签是MASM中代码部分之外的错误.我不确定是否有办法声明仅不是MASM变量".请参见评论中的讨论.)
;;我不确定这是否正确,我是凭记忆编造的;;而且我从未真正使用过MASM.我从SO答案知道语法..数据label1 :;仅"标签,没有数据db'abcd';小尾数"abcd"var2 dd 64636261h;no:所以符号变成一个变量,其大小从dd开始.代码函数:mov eax,[label1];我认为是合法的mov al,[label1];也合法mov eax,dword ptr [label1];一直有效movzx eax,字节ptr [label1 + 2];零将'c'扩展到EAXinc [label1];错误:操作数大小不明确mov eax,[var1];很好,两个操作数都是双字mov al,[var1];错误:操作数大小不匹配动态,字节ptr [var1];加载双字的低字节inc [var1];合法的:变量"暗含dword操作数的大小inc dword ptr [var1];同上和字节ptr [var1],〜20h;大写只是第一个字符,"abcd"变成"Abcd"
请注意,在MASM语法中, mov eax,var1
等效于 mov eax,[var1]
,但是我更喜欢使用 []
.
I'm currently doing assembly programming (16-bit) on DOSBox using MASM.
var1 dd 'abcd'
For the above code MASM is generating the error:
What is wrong with the syntax? I am simply storing 4 characters in a doubleword.
I am doing 16-bit assembly, so is that a problem? Can I only use db
and dw
because the other variables are greater than 16 bit?
var1 db 'abcd'
(not dd
) puts the 4 bytes you want into memory in source order.
Convenience in writing the initializer, dd 1234h
is more convenient than db 34h, 12h, 0, 0
but assembles identical data into the output file. Also, the way MASM treats them as implying an operand-size when you use the symbol.
Later versions of MASM do accept dd 'abcd'
, but they endian flip it. (Instead of assembling bytes into memory in source order like NASM does.) See @RossRidge's answer for MASM details.
NASM will accept mov eax, 'abcd'
or dd 'abcd'
just fine: multi-character literals are just another form of integer literal, with the first byte first in memory (the least significant), because x86 is little endian. i.e. in NASM, multi-character integer literals have a memory order that matches their source order.
But MASM reverses them when used with dd
or dw
, so the first character becomes the most significant byte of an integer, and memory order is the reverse of source order. It may be a good idea to avoid it even in MASM versions that support the syntax, and use hex ASCII codes plus a comment.
In MASM, var1 dd
vs. db
also sets a default operand-size for accessing the data, if you declare it as a variable instead of a label.
Using var1 db ...
means you'll have to use an explicit dword ptr
any time you want to access all 4 bytes with mov eax, [var1]
. Without dword ptr [var1]
, MASM will complain about operand-size mismatch.
But if you declare it as just a plain label, not tied to any db or dd directives that assemble bytes into memory, I think you can freely use it with any size.
(Update: apparently a label with a :
is an error in MASM outside of code sections. I'm not sure if there is a way to declare just a data label that isn't a MASM "variable". See discussion in comments.)
;; 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'
Note that mov eax, var1
is equivalent to mov eax, [var1]
in MASM syntax, but I prefer making the memory reference explicit by using []
.
这篇关于如何用汇编语言在定义的双字中存储4个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!