代码,静态,堆栈和堆段实现



我知道每个段的目的,但我想知道实际上在c或c++等语言中实现了它们?

它们是由c/c++编译器程序员在编写语言实现时编写的吗?或者这些段是在操作系统/硬件级别实现的(也许当操作系统为程序选择地址空间时)?

我把堆栈帧想象成一个简单的c结构体,它在每次函数调用时都被推入堆栈。我把堆想象成一个动态数组等等

这有点粗略-硬件架构,内存模型等都会影响C/c++实现可能具有"段"的方式。旧的cpu有限制,导致更复杂的"段"集(iAPX 286 -记得吗?)所以就把这当作一个粗略的介绍,谷歌一下流行词,…

目标代码包含由可执行语句产生的代码:由汇编机器指令产生的字节。这将进入一个代码段,这将(通常)导致内存段受到写保护。

目标代码包含由汇编的数据定义语句产生的data: bytes,经过一些初始化(或者在C/c++中默认为零),这将进入一个数据段,没有访问限制。

CPU的工作方式需要堆栈:在堆栈上压入返回地址,并通过压入函数参数来实现最有效的参数传递约定。"堆栈帧"部分是"按惯例",但通常它由返回地址和参数组成;为局部变量保留额外的空间:每个实例化一组(如果函数是递归的,这一点很重要)。

堆只是一个内存区域,其中分配(malloc, new)正在提供服务。它通常分配在代码和数据段之外。堆栈可以从堆中取出——这里取决于你是只有一个堆栈段还是几个(想想线程)。

另外,注意有几种目标代码"格式"或"语言",也就是说,这些片段如何在目标代码中定义的方式。这取决于系统的加载程序可以处理什么:一种这样的格式被称为"a.out",另一种是"ELF"。编译器必须遵循格式和可能性

它们是由c/c++编译器程序员在编写语言实现时编写的吗?或者这些段是在操作系统/硬件级别实现的(也许当操作系统为程序选择地址空间时)?

段入口点主要在工具链的链接阶段(和链接程序)进行管理。

在这个意义上,是的,这些是由编译器开发人员实现的。

你可以提供你自己的链接器脚本,在那里你可以指定这些段应该出现在哪个具体的内存地址,以及这些内存地址是指ROM还是RAM。

我把堆栈帧想象成一个简单的c结构体,它在每次函数调用时都被推入堆栈。我把堆想象成一个动态数组,等等…

这根本不是那么简单恐怕:

  • 堆栈帧通常还需要跟踪本地实例化的变量,在异常时展开堆栈所需的信息等。
  • 堆分配的内存需要一些基本的机制来跟踪分配的内存块及其实际大小。
  • 静态内存初始化和类初始化需要运行静态类的构造函数。

最新更新