我正在尝试调查在程序集中定义标签之间的区别,这是一个示例
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
答案 0 :(得分:5)
你在这里谈论两件不同的事情。
db,dw,dd之间的区别
杰斯特给了你正确答案。以下是NASM手册中的两个示例,它们可以帮助您理解它。
使用dw时,将以1个字(2个字节)为单位创建存储。因此它只能具有2,4,6,8 ......等大小的字节。在这个例子中,你有一个3 Bytes' 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
答案 1 :(得分:2)
唯一的区别是存储空间大小。 dw
将始终使用多个2
字节,而dd
将使用4
。
是的,您的最后两个示例会加载地址。