【问题标题】:x86 Assembly: What's the main prologue and epilogue?x86 大会:主要的序言和结语是什么?
【发布时间】:2009-11-12 19:07:08
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c assembly x86 nasm


    【解决方案1】:

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

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

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

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

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

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

    【讨论】:

    • 在 C 项目中,您所说的所有这些设置都是在调用 main 之前自动处理的(并且在 main 返回后自动发生退出事件)。现在您可能会问,“什么是 C 项目?”。嗯,这是一个有点棘手的问题,但基本上,如果你有一个“主”函数并与 libc (-lc) 链接,那么即使代码中的每个函数都是用 asm 编写的,你也是作为 C 项目工作的。
    【解决方案2】:

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

    如果您在 asm 中编写 main,您可能必须处理 main 实际上被称为 _main 或使用替代调用约定(尤其是在 Windows 下)或其他奇怪的事情,例如 C 编译器在生成代码时自动为您处理名称为“main”的函数。这样一来,您也不必这样做。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2011-03-14
        • 1970-01-01
        • 2011-09-02
        • 2011-08-26
        • 2016-06-01
        • 1970-01-01
        • 2010-11-13
        • 2015-12-04
        • 1970-01-01
        相关资源
        最近更新 更多