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

时间:2016-08-09 20:49:44

标签: string assembly x86 nasm masm

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

Digits: db "0123456789ABCDEF"

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

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

那么当我将变量定义为 byte 时,它意味着什么? 双字?我没有看到差异。由于我的误解,告诉字符串所需的数据类型似乎是多余的。

PD This question无法帮助我理解。

3 个答案:

答案 0 :(得分:5)

关联问题的答案之一引用了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时,区别在于会使用零填充元素大小的倍数。< / p>

根据@Jose's comment,一些汇编程序可能对dddw字符串常量使用不同的字节顺序。在NASM语法中,字符串始终以与引用常量中出现的顺序相同的顺序存储在内存中。

您可以将其与NASM(例如,进入默认的平面二进制输出)进行汇编,并使用hexdump -C或其他内容来确认字节顺序和填充量。

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

;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隐式长度字符串。)

答案 1 :(得分:1)

我想澄清一些事情:

example: db 'ABCDE';

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

ex2: db 1 ;

保留一个包含1的字节

ex3: db "cool;

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

ex4: db "cool", 1, 3;

保留3个字节?

答案:ex4是6个字节

答案 2 :(得分:-1)

对于字符串中的每个字符&#34; 0123456789ABCDEF&#34;你只需要一个字节。因此,字符串将占用内存中的16个字节。

如果声明:

vark db 1

你可以做到这一点:

mov [vark],128

并且不能:

mov [vark],1024

但在这种情况下:

vark dw 1

你可以。