NASM中装配中的截面和标签有什么区别?

ovr*_*ity 0 assembly label nasm sections

我目前正在通过 NASM 汇编器学习汇编,但我陷入了sectionlabel之间的区别。我知道section .dat, .bssor.text被用作变量声明或初始化的标准以及作为链接器钩子,例如main()在 C 中。而且,标签用于分配代码中的一个 部分。那么这背后有什么不为人知的真相呢?

Fra*_*ler 6

嗯,有一个很好的手册,你知道。http://www.nasm.us如果你还没有得到它。

您使用的输出格式很重要 --f开关。一般来说......section并且segment是别名,它们做同样的事情。它们不区分大小写,您可以SEGMENT根据需要使用。大多数输出​​格式(不是-f obj)都有“已知名称” - .text.data.bss(以及更多)。这些是区分大小写的 -section .TEXT可能不会做你想要的。通常,section .text是可执行的,但只读。尝试写入它会导致分段错误(或任何 Windows 调用它 - GPF?)。section .data用于您的初始化数据 -msg db "Hello World!", 0frooble_count dd 42. section .bss用于未初始化的数据,它只保留内存空间 - 不包含在磁盘文件中。您只能在那里使用“保留”伪指令 - resb, resw,resd等。它后面的参数表示您要保留多少字节(等)。在-f bin输出格式中,没有节/段(这就是使它成为“平面二进制”的原因)——Nasm 只是.text先制作,然后移动.data.bss最后——你可以按照你想要的任何顺序编写它们。

标签不定义一个部分!Nasm 只是将它们转换为数字——它们在你的代码中出现的地址——这就是你的可执行文件中出现的内容。您可以将标签用作变量名称,或用作您可能想要calljmp要使用的代码中的点。纳斯姆也是如此。一些汇编程序“记住”了您所说的变量的大小,如果您尝试错误地使用它,则会抛出错误。Nasm 有健忘症 - 你可以这样做mov [mybyte], eax毫无怨言。有时这很有用,但更多时候是错误。“太大”的变量通常不是问题——“太小”的变量会导致错误,而这种错误通常要到后来才会出现。很难调试!标签不能以十进制数字开头(并且数字必须以十进制数字开头)。以句点(点)开头的标签是局部标签。它的范围是从最后一个非本地标签到下一个非本地标签。有关(更多)详细信息,请参阅友好手册 - 这只是一个介绍。

“main”这个词对 Nasm 没有什么特别的意思,但对 C 来说是已知的(如果你链接到 C)。有些编译器会拼写它main,有些编译器_main(OpenWatcom)甚至会拼写它main_。它是入口点 - 当控制权传递给您的程序时执行开始。它不需要是第一件事section .text - 但应该在该部分中,并且应该声明为“全局”以告诉链接器有关它的信息。“_start”是 Linux(等)的默认入口点。与“main”不同,它不是called,所以你不能ret从它。可以使用另一个名称,但您需要告诉 ld ( -e myentry)。也应该如此global

现在就够了。请参阅手册,如果(哈!)您有其他问题,请回来。

  • 很确定`bss`不是“未初始化”。它是隐式零初始化的,因为操作系统分配给程序的所有页面都被清零以防止一个程序读取另一个程序的旧数据。 (2认同)