代码之家  ›  专栏  ›  技术社区  ›  Giuliano Vilela

x86大会:主要的序言和结尾是什么?

  •  0
  • Giuliano Vilela  · 技术社区  · 15 年前

    我在跟随 this tutorial 在x86程序集上。到目前为止,每个示例都使用作者所称的“C驱动程序”程序(用汇编模块编译)作为一些“初始化”的手段。比如:

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

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

    信息:我在windows xp上,32位框,使用nasm assembler和mingw32-gcc进行链接。

    3 回复  |  直到 7 年前
        1
  •  5
  •   Dipstick    15 年前

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

    在Windows/Unixy系统上,所讨论的代码通常非常简单——通常会进行一些库初始化(打开stdin、stdout、stderr、设置时区等),设置环境,处理传递给main的命令行;捕捉main()的返回,以及调用exit等。

    大多数C库中的启动代码都在一个名为crt0.c、crt1.c或类似文件(crt=c运行时)中。

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

    这是指向BSD C启动代码的链接- link text

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

        2
  •  0
  •   Southern Hospitality    15 年前

    如果你愿意的话,你可以把你的主要部分写在汇编中。但是很多人希望将调试语句放在主目录中,而这些在C中比在ASM中更容易。

    如果您在asm中编写main,那么您可能需要处理实际被调用的main,或者使用备用调用约定(特别是在Windows下)或者其他一些奇怪的事情,比如C编译器在为名为“main”的函数生成代码时自动为您处理这些事情。这样做,你也不必这么做。

        3
  •  0
  •   terry    15 年前

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

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