c - 启动时存储的函数内部定义的本地数据在哪里

标签 c function struct compilation stack

我了解全局数据将存储在 .BSS 或 .data 段中。

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

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

最佳答案

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

如果是局部变量:
写入占位符的“地址”值是相对的,是启动函数时堆栈位置“顶部”的偏移量。
它的其他确定方式与全局占位符的值类似。堆栈上的位置受到访问变量的影响,可以选择使用结构成员的子偏移量。实际地址由堆栈位置(即堆栈指针的值)加上占位符中找到的相对偏移量确定。

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

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

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

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

关于c - 启动时存储的函数内部定义的本地数据在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43270183/

相关文章:

c - 哪个函数告诉我内核将本地套接字绑定(bind)到哪个地址?

c pointer assignment to pointer to pointer 是什么意思

Java 将函数传递给方法

javascript - Onclick 函数更改为所有更改元素的相同函数

C - 无法从 void 指针访问结构元素值

go - 声明类型 *big.Int 溢出常量 golang

c++ - 如何检查用户是否输入了有效值?

c - Bricx 命令中心出现奇怪的编译器错误

c - 在 C 中递归文件时如何打印整个路径名和单个路径名?

c++ - Windows中的互斥问题