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

标签 assembly masm x86-16

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

var1 dd 'abcd'

对于上述代码,MASM 生成错误:

A2010: syntax error

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

我正在进行 16 位汇编,所以这是一个问题吗?我可以只使用 dbdw 因为其他变量都大于 16 位吗?

最佳答案

var1 db 'abcd'(不是 dd)将所需的 4 个字节按源代码顺序放入内存中。

what is the purpose of having variables other than db?

方便编写初始化程序,dd 1234hdb 34h, 12h, 0, 0 更方便,但将相同的数据组装到输出文件中。此外,当您使用符号时,MASM 将它们视为暗示操作数大小的方式。

MASM 的更高版本确实接受 dd 'abcd',但它们的字节序翻转。 (而不是像 NASM 那样按源顺序将字节组装到内存中。)请参阅 @RossRidge's answer for MASM details .

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

但 MASM 在与 dddw 一起使用时会反转它们,因此第一个字符成为整数的最高有效字节,并且内存顺序与源顺序相反。即使在支持语法的 MASM 版本中也避免使用它可能是一个好主意,并使用十六进制 ASCII 代码加注释。

<小时/>

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

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

但是,如果您将其声明为只是一个普通标签,而不与任何将字节组装到内存中的 db 或 dd 指令绑定(bind),我认为您可以自由地使用任何大小的它。

(更新:显然带有 : 的标签是 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],但我更喜欢使用 [ 显式地显示内存引用]

关于assembly - 如何用汇编语言在定义双字中存储4个字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281407/

相关文章:

gcc - 在 GCC 中转储寄存器的值

c - 在缓冲区溢出返回地址被不正确的地址覆盖,但它仍然有效

assembly - masm 错误 A2075 : jump destination too far : by 30 bytes

c - Switch 语句的工作原理

haskell - 分析高性能 Haskell 代码

assembly - 在程序集中添加两个变量

assembly - x86 程序集中的冲突标志 : movsx then unsigned compare/branch?

c - 如何使用 Bruce 的 C 编译器进行编译以获得在 8086 处理器上运行的 asm 文件

cpu-registers - 英特尔 8086 : Why 4 memory segments

assembly - 来自 AT&T 语法的 Intel Assembly ljmp 语法