在C中组织虚拟内存

对于以下每一个,它看起来在哪里存储在内存中,以及以什么顺序: 全局变量局部变量静态局部变量函数参数全局常量局部常量函数本身(并且主要是一个特例?), 动态分配变量

我如何评估这个实验,即使用C代码?

我知道
全局变量 - 数据
静态变量 - 数据
常数数据类型 - 代码
局部变量(在函数中声明和定义) - 堆栈
在主函数中声明和定义的变量 - 堆栈
指针(例如: char *arr,int *arr ) - 数据或堆栈
动态分配的空间(使用malloc,calloc) - 堆


你可以编写一些代码来创建上述所有内容,然后打印出他们的地址。 例如:

void func(int a) {
    int i = 0;
    printf("local i address is %xn", &i);
    printf("parameter a address is %xn", &a);
}

printf("func address is %xn", (void *) &func);

注意函数地址有点棘手,你必须将它转换为void *,并且当你使用函数的地址时,你可以省略()。 比较内存地址,你会开始得到一张图片或东西。 通常,文本(指令)位于底部(最接近0x0000),堆位于中间,堆栈从顶部开始向下增长。


理论上

就内存位置而言,指针与其他变量没有区别。

局部变量和参数可以分配在堆栈中或直接分配到寄存器中。

常量字符串将被存储在一个特殊的数据部分,但基本上与数据类型相同。

数字常量本身不会存储在任何地方,它们将被放入其他变量或直接转换为CPU指令。
例如int a = 5; 将恒定5存储到变量a (实际存储器是联系在一起的变量,而不是常量),但a *= 5将生成所必需的代码乘以a由恒定5。

就内存位置而言, main只是一个像其他任何函数一样的函数。 局部main变量与任何其他局部变量没有区别, main代码与任何其他函数一样位于代码段的某处, argcargv只是与其他任何函数相同的参数(它们由调用main函数的启动代码提供)等等。

代码生成

现在,如果你想知道编译器和运行库在何处放置所有这些东西,可以编写一个小程序来定义每一个程序,并要求编译器生成程序集清单。 然后你会看到每个元素是如何存储的。

对于堆数据,您将看到对malloc的调用,它负责与动态内存分配程序进行交互。

对于堆栈数据,您将看到对堆栈指针(x86体系结构上的ebp寄存器)的奇怪引用,它们都将用于参数和(自动)本地变量。

对于全局/静态数据,您会看到以变量命名的标签。

常量字符串可能会标上一个糟糕的名字,但您会注意到它们都会进入一段(通常名为bss),它们将链接到数据旁边。

运行时地址

或者,您可以运行该程序并要求它打印每个元素的地址。 但是,这不会显示注册表的使用情况。

如果使用变量地址,则会强制编译器将其放入内存中,否则可能会将其保存到寄存器中。

还要注意内存组织是编译器和系统相关的。 用gcc和MSVC编译的相同代码可能以完全不同的顺序具有完全不同的地址和元素。

代码优化器可能也会做一些奇怪的事情,所以我建议先编译您的示例代码,并禁用所有优化。
看看编译器做什么来获得大小和/或速度可能会很有趣。

链接地址: http://www.djcxy.com/p/14475.html

上一篇: Organization of Virtual Memory in C

下一篇: Where are Parameter variables stored in memory?