【发布时间】:2018-04-30 08:58:52
【问题描述】:
我在“从头开始编程”一书中了解了汇编 (x86) 的全局工作原理。 在本书中,每个程序都以退出的中断调用结束。
但是,在 C 编译程序中,我发现程序以 ret 结尾。这假设有一个要弹出的地址,这将导致程序结束。
所以我的问题是: 这个地址是什么? (那里的代码是什么?)
【问题讨论】:
-
它们不以
ret结尾。main以ret结尾,但这不是二进制文件中的完整代码,运行时 C 库具有启动/拆卸代码,并且调用main并在之后正确退出。 (您可以在链接期间检查编译器开关以查看所有参数,以查看添加了哪些库以及真正的入口点在哪里) -
C 程序包含在一个包装器中,它设置数据等,并将参数提供给
main(int argc, char *argv[])。所以退出的系统调用来自包装器。 -
有一些启动代码在调用
main()之前为它设置环境(例如初始化标准输入、输出、错误文件流)。main()末尾的ret返回到该代码,这通常相当于exit(main(argc, argv, environ));。 (environ实际上很常见,但不是标准强制要求的。) -
是的 - 它通常被命名为“crt”(C 运行时),并以一种或另一种方式链接到您的编译代码。在非平凡操作系统上运行时,crt 将在 main() 返回后进行系统调用/中断以终止进程。
-
那里的代码非常特定于操作系统,可能还有版本,因为它是操作系统将程序加载到 ram 中并“调用”它,程序从该程序返回一个 ret 到操作系统放置调用它的代码。你读的书很可能是基于dos程序,在哪里可以得到“os”来清理你,称为exit。但即使有一个编译器也可以在编译器提供的引导程序中退出,以便 main 简单地返回。编译器必须针对其目标、操作系统和指令集进行调整