C语言 在启动时存储的函数中定义的本地数据在哪里



我知道全局数据将存储在 .BSS 或 .data 细分受众群。

但是,如果我有函数内部定义的结构等数据,则只有在调用函数时,此结构才会放置在堆栈上。

在调用函数之前,编译器在启动时将此数据存储在哪里? 我知道编译器会根据目标和调用约定等生成不同的汇编代码,但一般来说,这个本地结构是否必须首先存储在某个地方,以便编译器知道如何在调用函数时将其放在堆栈上?提前谢谢。

在全局变量(也是静态局部变量)的情况下:
编译器将全局变量作为特定地址和大小的内存部分进行访问。地址最初是一个占位符(很像变量的名称)。大小是隐式的,取决于编译器在程序集/机器代码中选择的访问类型。链接器/加载器知道大小,它确保下一个变量不重叠。
地址占位符在链接(例如嵌入式、静态、就地执行)或加载(例如 PC 上的程序、应用程序)期间被替换。

在局部变量的情况下
:写入占位符的"地址"值是相对的,在启动函数时堆栈位置"顶部"的偏移量。
否则,它将像全局占位符的值一样确定。堆栈上的位置受访问变量的影响,可以选择使用结构成员的子偏移量。实际地址确定为堆栈位置(即堆栈指针的值)加上占位符中的相对偏移量。

占位符实际上是偏移量列表,与实际的二进制代码一起存储在二进制(例如程序.exe)中。类似于"当您决定在内存中找到此变量的位置时,将地址写入此处列出的代码中的所有位置:..."。例如,写入这些位置将在字节中放置一个有意义的值,该值在执行期间将被解释为相对"MOV"汇编程序指令的文字偏移量;相对于例如指向 BSS 部分开头的部分指针。

简而言之,地址信息位于占位符列表中。这些列表可能根本不会在内存中找到,或者在执行时找不到。加载程序(包括填写占位符)后,不再需要这些列表。
大小信息是代码的一部分(例如,使用 8 位访问或 32 位访问),它是可变位置布局的一部分。每个变量都可以在前一个变量后面足够远的地方访问。

因此,更短地说,您正在寻找的信息在执行过程中一半是隐藏的,一半根本不在内存中。

我假设您的问题不是关于变量中的值。只是为了覆盖它:该值被初始化为0,一个常量初始化值,或者,特殊情况,根本不保留启动时内存中的任何内容。init 值位于基本上是常量列表的部分中。给定变量的常量确切位置与占位符相似。
对于局部变量,编译器通常不初始化,但可以配置为写入 0(这有点"昂贵")。这就是为什么在使用变量之前初始化变量是一种很好的做法。具有显式初始化的局部变量当然在堆栈帧设置期间初始化。

最新更新