6

根据我们的书,每个函数在 C 的运行时堆栈中都有一个激活记录。每个激活记录都有一个返回地址、动态链接和返回值。主要也有这些吗?

4

4 回答 4

6

所有这些术语都是纯粹的实现细节——C 没有“返回地址”或“动态链接”的概念。它甚至根本没有“堆栈”的概念。C 的大多数实现中都有这些对象,并且在这些实现中它们可能存在于main. 但是,不要求发生这种情况。

希望这可以帮助!

于 2013-03-18T01:08:17.790 回答
2

如果你反汇编函数,你会意识到大多数时候堆栈甚至不包含返回值——通常是 EAX 寄存器包含(intel x86)。您还可以查找“调用约定”——这在很大程度上取决于编译器。C 是一种语言,如何将其解释为机器代码并不是“它的”业务。

于 2013-03-18T01:12:54.620 回答
1

虽然这取决于实现,但值得研究使用 gcc 编译的 C 程序。如果你运行objdump -d executable,你会看到它被反汇编,你可以看到它的main()行为。这是一个例子:

08048680 <_start>: ... 8048689: 54 push %esp 804868a: 52 push %edx 804868b: 68 a0 8b 04 08 push $0x8048ba0 8048690: 68 30 8b 04 08 push $0x8048b30 8048695: 51 push %ecx 8048696: 56 push %esi 8048697: 68 f1 88 04 08 push $0x80488f1 804869c: e8 9f ff ff ff call 8048640 <__libc_start_main@plt> 80486a1: f4 hlt ... 080488f1 <main>: 80488f1: 55 push %ebp 80488f2: 89 e5 mov %esp,%ebp 80488f4: 57 push %edi 80488f5: 56 push %esi 80488f6: 53 push %ebx ... 8048b2b: 5b pop %ebx 8048b2c: 5e pop %esi 8048b2d: 5f pop %edi 8048b2e: 5d pop %ebp 8048b2f: c3 ret

您可以看到 main 的行为类似于常规函数,因为它正常返回。实际上,如果您查看linux 基础文档,您会发现__libc_start_main我们从中看到的调用_start实际上需要main像常规函数一样运行。

于 2015-03-31T06:29:09.517 回答
0

在 C/C++ 中,main()就像函数一样编写,但不是函数。例如,不允许调用main(),它有几个可能的原型(在 C 中不能这样做!)。从中得到的任何return东西都会传递给操作系统(程序结束)。

单个 C 实现可能会main()像从“外部”调用的函数一样处理统一性,但没有人强迫他们这样做(或不允许在不告诉任何人的情况下切换到其他形式)。有实现 C 的传统方法,但没有人被迫这样做。这只是我们典型架构中最简单的方法。

于 2013-03-18T02:06:55.563 回答