在x86中将string定义为字节(db)和将string定义为字/双字(dw / dd)有什么区别?

我试图调查大会定义标签之间的差异,这里是一个例子

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内容的调查显示,它包含一个地址,可能是string中前四个字母的地址,与第一个地址相同,尽pipe我在这里进行了推测。

我想澄清在这里真正发生了什么,并且这个声明实际上是将string中第一个字母的地址加载到一个寄存器中:

 Fin: db 'Final' mov ecx, Fin 

Solutions Collecting From Web of "在x86中将string定义为字节(db)和将string定义为字/双字(dw / dd)有什么区别?"

你在这里谈论两件不同的事情。

db,dw,dd之间的区别
杰斯特已经给你正确的答案了。 以下是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 

这将在eax中保存内存地址的前4个字节:

 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

唯一的区别是存储大小。 dw将始终使用2个字节的倍数,而dd将使用4

是的,你最后两个例子加载地址。