代码存储器和数据存储器中存储的内容

What is stored in Code memory and Data memory

有人可以解释一下代码和数据内存之间的区别吗?我知道代码存储在 Flash 中,数据存储在 RAM 中,但我很困惑。

#include <iostream>
using namespace std;

int main()
{
    int a =10, b=20;
    int c = a+b;
    return 0;
}

这里a,b,c都存储在数据内存(RAM)中,但是代码内存中存储的是什么?整个代码是否存储在代码内存中?如果是,那么这是否意味着我们将 a、b、c 存储在数据和代码存储器中。

快速简化:

代码内存 存储从您的 C++ 代码段(ROM)编译的机器语言指令序列。

程序创建和操作的实际数据存储在RAM中,可以理解为由stack构成heap:数据存储在较慢但较大的堆中,而其地址由堆栈中的指针保留。堆栈托管在更快的内存寄存器中。

堆栈中的指针在 ROM 中的当前指令行指示时检索堆中的数据,或者通常在需要时更多。

在您的示例中,许多场景基于您的编译器的优化级别。

“代码内存”中的常量

在下面的代码中:

int a =10, b=20;
int c = a+b;
return 0;

变量ab是常量,它们不会改变。编译器可以对此进行优化并将它们优化为: 整数 c = 10 + 20; 所以值 10 和 20 可以放入代码内存,消除变量 ab.

注册不是内存

允许编译器将变量ab分配给寄存器。寄存器在处理器中,所以不占用任何 RAM 或内存 space。寄存器也不是代码 space 的一部分。 (这可能发生是因为没有语句需要 ab 的地址).

删除所有代码

在更高的优化设置上,编译器可以删除所有代码并替换为 return 0
变量 ab 未更改。
变量 c 已更改但未被任何其他语句使用。
您的程序没有效果(没有打印任何内容,没有写入硬件等外部操作)。
因此你的程序可以减少到 return 0;.

代码内存与数据内存

一般来说,处理器指令放在一个你称之为“代码内存”的段中。这实际上可能驻留在 RAM 中,而不是在闪存或 ROM 中。例如,在 PC 上,您的代码可以从硬盘驱动器加载到 RAM 中并在 RAM 中执行。与 Flash 类似,您的代码可以从 Flash 加载到 RAM 中并在 RAM 中执行。

常量,如数字,可以放在 Read-Only 段或代码段中。许多处理器可以从代码段加载常量(参见 ARM 和 Intel 汇编指令)。 Read-Only 段可以存在于只读设备(ROM 或闪存)中,也可以存在于 RAM(或硬盘驱动器等设备)中。您可以保证的是,代码不会写入 Read-Only 段。

数据内存不同。 C++ 语言至少有 3 个“数据”内存区域(变量所在的区域): 1) Local (a.k.a.stack),短生命周期变量所在的区域; 2)动态内存(a.k.a.heap),使用newmalloc和3)Automatic/Global变量分配。这些内存区可以放在任何地方,只要内存具备读写能力即可。它们不需要很快,只需要读写即可(例如,硬盘可以用作数据存储器)。

内存组织比有Code、Stack和Heap更复杂。在嵌入式系统世界中,内存可以放置在 non-standard 个位置,并且可能需要有更详细的内存段,以便它们可以放置在不同的区域。例如,嵌入式系统可能希望将常量放入闪存中,以便可以轻松更改它们(即使在代码段中访问它们可能更有效)。某些代码可能需要放入处理器的引导区(由处理器制造商编程)。某些嵌入式系统可能具有 non-volatile 内存(例如电池供电内存),其行为类似于 Read-Only 内存。

相信你的编译器

相信您的编译器会尽可能将代码、数据和变量放在最高效的区域。您的编译器了解您的平台并将为您做出最佳决策。如果您需要更改编译器的设置,您可以,但您应该真正知道您在做什么以及为什么需要更改它们。大多数 PC 平台将代码从硬盘驱动器(或 SSD)加载到 RAM 中并从 RAM 中执行代码。嵌入式系统是不同的,取决于硬件设备。代码可能 运行 来自闪存,因为该平台的 RAM 最少。有些可能将压缩的代码存储在串行访问 read-only 设备中,并且必须在执行前解压缩到 RAM 中。在这些情况下,编译器针对这些专业化进行了配置。因此,请相信您的编译器,让它将代码和数据放入正确的段和位置。