c - 内存段定义在哪里?

标签 c compilation embedded

我刚刚了解了不同的内存段,例如:文本、数据、堆栈和堆。我的问题是:

1- 这些部分之间的界限在哪里定义?是在 Compiler 还是 OS 中?

2- 编译器或操作系统如何知道哪些地址属于每个部分?我们应该在任何地方定义它吗?

最佳答案

这个答案是从更特殊用途的嵌入式系统的角度出发的,而不是从运行 Linux 等操作系统的更通用的计算平台的角度出发的。

Where the boundaries between these sections are defined? Is it in Compiler or OS?

编译器和操作系统都不会这样做。 链接器 决定内存部分的位置。编译器从源代码生成目标文件。链接器使用链接器脚本文件在内存中定位目标文件。链接器脚本(或链接器指令)文件是项目的一部分,用于标识各种存储器类型(如 ROM 和 RAM)的类型、大小和地址。链接器程序使用链接描述文件中的信息来了解每个存储器的起始位置。然后链接器将目标文件中的每种类型的内存定位到适当的内存部分。例如,代码进入通常位于 ROM 中的 .text 部分。变量进入位于 RAM 中的 .data 或 .bss 部分。堆栈和堆也进入 RAM。当链接器填充一个部分时,它会了解该部分的大小,然后可以知道从哪里开始下一个部分。例如,.bss 部分可能从 .data 部分结束的地方开始。

堆栈和堆的大小可以在链接器脚本文件中指定,也可以作为 IDE 中的项目选项指定。

嵌入式系统的 IDE 通常会在您创建项目时自动提供一个通用的链接描述文件。通用链接器文件适用于许多项目,因此您可能永远不必自定义它。但是当您进一步自定义目标硬件和应用程序时,您可能会发现还需要自定义链接描述文件。例如,如果您向电路板添加外部 ROM 或 RAM,则需要将有关该存储器的信息添加到链接描述文件,以便链接器知道如何在其中定位内容。

链接器可以生成一个映射文件,描述每个部分在内存中的位置。默认情况下可能不会生成 map 文件,如果您想查看它,您可能需要打开构建选项。

How the compiler or OS know which addresses belong to each section?

好吧,我不相信编译器或操作系统实际上知道这些信息,至少在您可以查询它们以获取信息的意义上。编译器在链接器找到内存部分之前就已经完成了它的工作,所以编译器不知道这些信息。操作系统,我该如何解释呢?嵌入式应用程序甚至可能不使用操作系统。操作系统只是一些为应用程序提供服务的代码。操作系统不知道也不关心内存部分的边界在哪里。在操作系统运行时,所有这些信息都已经嵌入到可执行代码中。

Should we define it anywhere?

查看链接器脚本(或链接器指令)文件并阅读链接器手册。链接器脚本是链接器的输入,提供内存的粗略轮廓。链接器定位内存中的所有内容并确定每个部分的范围。

关于c - 内存段定义在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41094027/

相关文章:

c - 我需要一个工具来在单个文本文件或一组文本文件中查找重复或相似的文本 block

.net - 将 .NET 项目编译为独立 native 二进制文件的可用工具有哪些?

java - 如何使用 C++ 编译 .java 文件

用于嵌入式系统的 C XML 库

根据值干净地访问结构数组

c - '-c' 选项在 GCC 中有什么作用?

c - 在 Swig 中,如何处理应该更新字符串内容的函数?

c - C 语言中 Double 变成 nan

c++ - 使用#ifndef 时具体定义了什么

c++ - SAMD21如何使用TCC设置PWM?