dw 和 dd 与字符串的 db 指令有何不同?

How are dw and dd different from db directives for strings?

假设我想在 运行 我的汇编程序之前定义一个初始化变量字符串(在 section .data 中)。我选择创建的变量称为 Digits,它是一个包含所有十六进制符号的字符串。

Digits: db "0123456789ABCDEF"

我用db定义了变量,也就是说define byte。这是否意味着 Digits 变量是 8 位长?这对我来说似乎没有意义,因为:

字符串中的每个字符都是一个 ASCII 字符,因此每个字符需要 2 个字节。整个字符串总共需要 32 个字节!

那么我定义变量为byte是什么意思呢? 单词双字?我看不出有什么区别。由于我的误解,告诉字符串你需要的数据类型似乎是多余的。

PDThis question 没有帮助我理解。

NASM回答,MASM完全不一样

链接问题的其中一个答案引用了 NASM 手册的示例,它确实回答了您的问题。根据要求,我将针对所有三种情况对其进行扩展(并更正小写与大写 ASCII 编码错误!):

db   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45                (5 bytes)
dw   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00           (6 bytes, 3 words)
dd   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 2 doublewords)
dq   'ABCDE'     ; 0x41 0x42 0x43 0x44 0x45 0x00 0x00 0x00 (8 bytes, 1 quadword)

因此不同之处在于,当您使用 dddw 而不是 db.

根据 ,某些 assemblers 可能对 dddw 字符串常量使用不同的字节顺序。在 NASM 语法中,字符串总是按照它在引用常量中出现的相同顺序存储在内存中。

您可以 assemble 使用 NASM (例如进入默认的平面二进制输出)并使用 hexdump -C 或其他东西来确认字节顺序和填充量。


请注意,元素大小的这种填充适用于每个以逗号分隔的元素。所以看似无辜的dd '%lf', 10, 0其实assemble是这样的:

;dd   '%lf',    10,        0
db    '%lf',0,  10,0,0,0,  0,0,0,0        ;; equivalent with db

注意换行前的0;如果将指向此的指针传递给 printf,则 C 字符串只是 "%lf",由第一个 0 字节终止。

(write 系统调用或具有显式长度的 fwrite 函数将打印整个内容,包括 0 字节,因为这些函数处理二进制数据,而不是 C 隐式-长度字符串。)


另请注意,在 NASM 中,您可以执行 mov dword [rdi], "abc" 之类的操作以将“abc[=57=]”存储到内存中。即,多字符文字在 NASM.

中的任何上下文中都用作数字文字

MASM 非常不同

有关更多信息,请参阅 。即使在 dd "abcd" 中,MASM 也会破坏您的字符串,与源顺序相比,颠倒块内的字节顺序。

对于字符串“0123456789ABCDEF”中的每个字符,您只需要一个字节。因此,该字符串将在内存中占用 16 个字节。

在这种声明的情况下:

vark 数据库 1

你可以做到这一点:

mov [vark],128

并且不能:

mov [vark],1024

但在这种情况下:

vark dw 1

可以。

我想澄清一件事:

example: db 'ABCDE';

这里一共保留5个字节,每个字节包含一个字母。

ex2: db 1 ;

保留一个包含1的字节

ex3: db "cool;

保留4个字节,每个字节包含一个字母

ex4: db "cool", 1, 3;

保留 3 个字节?

答案:ex4 是 6 个字节