这是非常广泛的,但答案就是以上所有。例如,在 ARM cortex-m 方面,ARM 定义了用于代码、外围设备等的内存空间。如果你不遵循这些,那么事情就不会按你希望的方式工作。同时,每个处理器都有一个引导方案,通常是一个固定地址,用于获取第一条指令或复位向量。所以系统工程师需要围绕它设计电路板或芯片。由于这需要是非易失性的,因此您通常不会在该地址空间(或外围设备)看到 ram,这意味着它们在其他地方,因此可以选择该产品。
一般的向量表或软件中断或其他可能具有硬编码地址的东西会影响您设计系统的方式。然后,您会遇到可能是也可能不是历史侥幸的事情。 IBM PC,他们是谁、如何以及为什么选择他们选择的地址空间?无关紧要,但它为兼容设备设定了一个标准,并一直延续到今天(有一些演变)。
上面的内容只是让你到达没有 ram 的地方。
根据先前设计的约定,大多数情况下基本上是任意的,当前的设计可能会为 ram 使用某些内存空间。
文本堆堆栈模型有些明显,代码通过地址空间向前运行。堆栈是动态的,让堆栈在内存空间中向上增长是没有意义的,而是从顶部向下增长,尽管随着我们的发展,我们一开始可能没有理解这一点。当然,今天有了 MMU,你就拥有了类似于历史的虚拟空间,但物理空间是你想要的任何东西,散布在 ram 周围的碎片中。当堆栈没有意义时,这会将内存留在中间供程序动态分配。
在 .text、.data、heap 和 stack 的虚拟(或真实)地址空间中,是当今实现(windows、linux 等)中操作系统和编译器的组合。作为一名程序员,如果您完全了解操作系统规则,则可以自定义链接描述文件,使其与该操作系统的目标编译器的默认链接脚本不完全相同。并且没有理由假设 llvm 和 gcc 针对相同的目标和操作系统遵循相同的解决方案。尽管您可能会看到他们根据谁先来使用相同或相似的解决方案,或者如果程序员(包括他们的内部开发人员)在工具之间来回切换,他们的生活会更轻松。
现在这是针对在操作系统上运行的应用程序。当您进入裸机时,包括操作系统本身(可以被视为裸机程序本身),情况就会发生变化。通常,您是程序员来创建满足您需求的内存空间。您将对诸如 mcus 之类的事物制定规则,其中非易失性和易失性空间由芯片供应商确定。但是在那个空间内,您可以选择,仅仅因为您可以在闪存/ROM 之外运行代码,您不必这样做,并且出于性能或其他原因可能会选择不这样做。同样对于向量表,您可以选择使用启动芯片所需的基于闪存的地址空间,但取决于产品(不一定是处理器内核,芯片供应商控制地址空间),您可能有选择,也可能没有。
因此,当您使用裸机时,尤其是当您从闪存启动时,规则就不存在了。 .data 例如需要存在两个地方,一个是非易失性内存,一个是复制到它在 ram 中的位置。 bss 类似的东西。 .text 可以根据您的选择同时存在于闪存和/或内存中,内存部分从闪存复制(或下载)。
由于您没有远程提供足够的信息,答案只能是“取决于”和“以上所有”。