如何用汇编语言在定义的双字中存储4个字符?

时间:2019-05-23 18:56:57

标签: assembly masm x86-16

我目前正在使用MASM在DOSBox上进行汇编编程(16位)。

var1 dd 'abcd'

对于上面的代码,MASM正在生成错误:

  

A2010:语法错误

语法有什么问题?我只是在一个双字中存储4个字符。

我正在执行16位汇编,所以有问题吗?因为其他变量大于16位,我只能使用dbdw吗?

1 个答案:

答案 0 :(得分:3)

var1 db 'abcd'按照zx485的说明,将所需的字节按照所需的顺序放入内存中。

  

拥有db以外的变量的目的是什么?

方便编写初始化程序,dd 1234hdb 34h, 12h, 0, 0更方便。

@MichaelPetch says,MASM的更高版本确实接受dd 'abcd',但它们不像NASM那样进行endian翻转。

NASM会接受mov eax, 'abcd'dd 'abcd'就好了:多字符字面量只是整数字面量的另一种形式,第一个字节在内存中优先(最低有效),因为x86的字节序是低位的。也就是说,在NASM中,多字符整数文字的存储顺序与其源顺序相匹配。

但是,当与dddw一起使用时,MASM会将它们反转,因此第一个字符成为整数的 most 有效字节,并且存储顺序与源代码相反订购。即使在支持该语法的MASM版本中也应避免使用它,并使用十六进制ASCII码加上注释。


在MASM中,如果将其声明为变量而不是标签,它还会设置用于访问数据的默认操作数大小。

使用var1 db ...意味着您每次要使用dword ptr访问所有4个字节时都必须使用显式的mov eax, [var1]。如果没有dword ptr [var1],MASM将抱怨操作数大小不匹配。

但是,如果您仅将其声明为普通标签,而不是将字节组装到内存中的任何db或dd指令绑定,则我认为您可以自由使用任意大小的标签。

(更新:显然,带有:的标签是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'

请注意,mov eax, var1与MASM语法中的mov eax, [var1]等效,但是我更喜欢使用[]使内存引用显式。