本文介绍了如何用汇编语言在定义的双字中存储4个字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用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个字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-17 16:13