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是什么意思呢? 单词? 双字?我看不出有什么区别。由于我的误解,告诉字符串你需要的数据类型似乎是多余的。
PD:This 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)
因此不同之处在于,当您使用 dd
或 dw
而不是 db
.
根据 ,某些 assemblers 可能对 dd
或 dw
字符串常量使用不同的字节顺序。在 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 个字节
假设我想在 运行 我的汇编程序之前定义一个初始化变量字符串(在 section .data
中)。我选择创建的变量称为 Digits
,它是一个包含所有十六进制符号的字符串。
Digits: db "0123456789ABCDEF"
我用db
定义了变量,也就是说define byte。这是否意味着 Digits
变量是 8 位长?这对我来说似乎没有意义,因为:
字符串中的每个字符都是一个 ASCII 字符,因此每个字符需要 2 个字节。整个字符串总共需要 32 个字节!
那么我定义变量为byte是什么意思呢? 单词? 双字?我看不出有什么区别。由于我的误解,告诉字符串你需要的数据类型似乎是多余的。
PD:This 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)
因此不同之处在于,当您使用 dd
或 dw
而不是 db
.
根据 dd
或 dw
字符串常量使用不同的字节顺序。在 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 个字节