在x86中将字符串定义为字节(db)和将字符串定义为words/double字(dw/dd)有什么区别
What is the difference between defining string as bytes (db) and defining strings as words/double words(dw/dd) in x86
我正在尝试研究在汇编中定义标签之间的区别,这是一个示例
ALabel: db 'Testing'
AAnotherLabel: dw 'Testing'
现在,让我将它们加载到 32 位寄存器中:
mov eax, [ALabel]
mov ebx, [AAnotherLabel]
根据 gdb 的调查,我发现 eax 和 ebx 的所有子寄存器都包含相同的值,看这里:
info register eax
0x64636261 //dcba
info register ebx
0x64636261 //dcba
他们是一样的!
在 Jeff Duntemann 的书中(使用 Linux 的汇编语言逐步编程)他展示了一个将字和双字放入寄存器的示例,但由于某种原因加载了偏移量(即地址像这样的值)
DoubleString: dd 'Stop'
mov edx, DoubleString
调查 edx 的内容表明它包含一个地址,可能是字符串中前四个字母的地址,而不是第一个地址,尽管我在这里推测。
我想澄清一下这里到底发生了什么,这条语句是否实际上将字符串中第一个字母的地址加载到寄存器中:
Fin: db 'Final'
mov ecx, Fin
唯一的区别是存储大小。 dw
将始终使用 2
字节的倍数,而 dd
将使用 4
.
是的,您最后两个示例加载了地址。
您在这里谈论的是两件不同的事情。
db、dw、dd的区别
Jester 已经给了你正确的答案。下面是 NASM 手册中的两个例子,应该可以帮助你理解它。
当您使用 dw 时,以 1 个字(2 个字节)为步长创建存储。因此它只能有 2、4、6、8 等字节的大小。在此示例中,您有一个 3 字节 'abc' 的字符串。它只需要 3 个字节,但因为您使用了 'dw',所以它有 4 个字节长。 4.字节用0填充。
fin: dw 'abc' ; 0x61 0x62 0x63 0x00 (string)
通过使用 db 而不是 dw,您可以在 1 字节的步骤中创建存储。这个将是 3 个字节长:
fin: db 'abc' ; 0x61 0x62 0x63 (string)
它们被称为伪指令,因为实际上,它们是您的汇编器的命令(在本例中为 NASM),它告诉他如何分配您的存储空间。它不是您的处理器必须读取的代码。来源:
3.2.1: http://www.nasm.us/doc/nasmdoc3.html
有括号和无括号
您谈到的另一件事是使用括号 [] 或不使用。这又是与 NASM 的语法有关的事情。当您不使用括号时,您告诉 NASM 使用该地址。这会将内存地址保存在eax中:
mov eax, fin
这会将内存地址的前 4 个字节保存在 eax 中:
mov eax, [fin]
关于你的最后一个问题:
DoubleString: dd 'Stop'
mov edx, DoubleString
DoubleString,内存地址,'Stop'
保存在edx中。每个地址对应一个字节。因此地址 DoubleString
直接指向字母 'S'
。地址Doublestring+1
指向下一个字节,其中存放字母't'
等。
来源:
2.2.2: http://www.nasm.us/doc/nasmdoc2.html#section-2.2.2
我正在尝试研究在汇编中定义标签之间的区别,这是一个示例
ALabel: db 'Testing'
AAnotherLabel: dw 'Testing'
现在,让我将它们加载到 32 位寄存器中:
mov eax, [ALabel]
mov ebx, [AAnotherLabel]
根据 gdb 的调查,我发现 eax 和 ebx 的所有子寄存器都包含相同的值,看这里:
info register eax
0x64636261 //dcba
info register ebx
0x64636261 //dcba
他们是一样的!
在 Jeff Duntemann 的书中(使用 Linux 的汇编语言逐步编程)他展示了一个将字和双字放入寄存器的示例,但由于某种原因加载了偏移量(即地址像这样的值)
DoubleString: dd 'Stop'
mov edx, DoubleString
调查 edx 的内容表明它包含一个地址,可能是字符串中前四个字母的地址,而不是第一个地址,尽管我在这里推测。
我想澄清一下这里到底发生了什么,这条语句是否实际上将字符串中第一个字母的地址加载到寄存器中:
Fin: db 'Final'
mov ecx, Fin
唯一的区别是存储大小。 dw
将始终使用 2
字节的倍数,而 dd
将使用 4
.
是的,您最后两个示例加载了地址。
您在这里谈论的是两件不同的事情。
db、dw、dd的区别
Jester 已经给了你正确的答案。下面是 NASM 手册中的两个例子,应该可以帮助你理解它。
当您使用 dw 时,以 1 个字(2 个字节)为步长创建存储。因此它只能有 2、4、6、8 等字节的大小。在此示例中,您有一个 3 字节 'abc' 的字符串。它只需要 3 个字节,但因为您使用了 'dw',所以它有 4 个字节长。 4.字节用0填充。
fin: dw 'abc' ; 0x61 0x62 0x63 0x00 (string)
通过使用 db 而不是 dw,您可以在 1 字节的步骤中创建存储。这个将是 3 个字节长:
fin: db 'abc' ; 0x61 0x62 0x63 (string)
它们被称为伪指令,因为实际上,它们是您的汇编器的命令(在本例中为 NASM),它告诉他如何分配您的存储空间。它不是您的处理器必须读取的代码。来源:
3.2.1: http://www.nasm.us/doc/nasmdoc3.html
有括号和无括号
您谈到的另一件事是使用括号 [] 或不使用。这又是与 NASM 的语法有关的事情。当您不使用括号时,您告诉 NASM 使用该地址。这会将内存地址保存在eax中:
mov eax, fin
这会将内存地址的前 4 个字节保存在 eax 中:
mov eax, [fin]
关于你的最后一个问题:
DoubleString: dd 'Stop'
mov edx, DoubleString
DoubleString,内存地址,'Stop'
保存在edx中。每个地址对应一个字节。因此地址 DoubleString
直接指向字母 'S'
。地址Doublestring+1
指向下一个字节,其中存放字母't'
等。
来源:
2.2.2: http://www.nasm.us/doc/nasmdoc2.html#section-2.2.2