x86大会:主要的序幕和结语是什么?

时间:2009-11-12 19:07:08

标签: c assembly x86 nasm

我在x86程序集上关注this tutorial。到目前为止,每个例子都使用作者称为“c-driver”程序,用汇编模块编译,用于某些“初始化”。类似的东西:

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

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

信息:我使用的是Windows XP,32位盒,使用NASM汇编程序和mingw32-gcc进行链接。

3 个答案:

答案 0 :(得分:5)

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

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

大多数c库中的启动代码位于一个名为crt0.c,crt1.c或类似文件的文件中(crt = c run time)。

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

以下是BSD c启动代码的链接 - link text

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

答案 1 :(得分:0)

如果需要,您可以在装配中编写主要内容。但是很多人都希望将调试语句放在main中,而且在C语言中比在asm中更容易。

如果您在asm中编写main,则可能必须处理main实际上被称为_main或使用备用调用约定(特别是在Windows下)或其他奇怪的事情,例如C编译器在生成代码时自动为您处理功能名为“main”。这样就可以让你无需这样做。

答案 2 :(得分:0)

在调用main()之前,必须初始化堆栈,寄存器和程序的文件段(data,rodata,bss等)。 C运行时库(CRT)提供此初始化。

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