0

我正在关注关于 x86 程序集的本教程。到目前为止,每个示例都使用作者所谓的“c-driver”程序,用汇编模块编译,作为某种“初始化”的手段。就像是:

int main(void) {
  int ret = asm_main();
  return ret;
}

然后 asm_main 函数正常编写,使用 C 调用约定。我想知道 C 编译器生成的所需初始化究竟是什么,以及它是否可以以可移植的方式完成。

信息:我在 Windows XP,32 位机器上,使用 NASM 汇编器和 mingw32-gcc 进行链接。

4

3 回答 3

6

初始化不是由 c 编译器生成的,它是 c 库的一部分(这使得为每个操作系统/处理器定制更容易)。

有问题的代码在 windows/unixy 系统上通常非常简单——通常会进行一些库初始化(打开 STDIN、STDOUT、STDERR、设置时区等)、设置环境、处理传递给 main 的命令行;捕获 main() 的返回并调用 exit 等。

大多数 c 库中的启动代码位于名为 crt0.c、crt1.c 或类似文件的文件中(crt = c 运行时间)。

在更原始或裸系统上,它还将设置堆栈和其他寄存器并清除 BSS 数据区域 - 在这种情况下,它通常在汇编程序中(通常是 crt0.S)。

这是 BSD c 启动代码的链接 -链接文本

mingw for windows 的启动代码在 crt1.c 中 - http://mingw.cvs.sourceforge.net/viewvc/mingw/runtime/

于 2009-11-12T20:50:57.023 回答
0

堆栈、寄存器和程序的文件部分(数据、rodata、bss 等)必须在调用 main() 之前初始化。C 运行时库 (CRT) 提供了这种初始化。

CRT 还提供在调用每个函数之前和之后执行的序言和结尾代码。序言和结语代码更新堆栈和帧指针。

于 2009-11-13T03:30:48.320 回答
0

如果你愿意,你可以在汇编中编写你的 main 。但是很多人希望将调试语句放在 main 中,而在 C 中比在 asm 中更容易。

如果您在 asm 中编写 main ,则可能必须处理 main 实际上被称为 _main 或使用备用调用约定(尤其是在 Windows 下)或其他奇怪的事情,例如 C 编译器在为具有名称“主要”。这样就可以了,因此您也不必这样做。

于 2009-11-12T21:06:50.217 回答