gpt4 book ai didi

c - 关于C程序内存布局的问题

转载 作者:行者123 更新时间:2023-12-02 22:01:53 27 4
gpt4 key购买 nike

我对 C 程序的内存布局有一些疑问。

文本段

这是我的第一个问题:

当我搜索文本段(或代码段)时,我读到“文本段包含可执行指令”。但是任何功能的可执行指令是什么?你能举一些不同的例子吗?

我还读到“文本段是可共享的,因此对于频繁执行的程序(如文本编辑器、C 编译器等),内存中只需要一个副本。”,但我无法在 C 之间建立连接程序和“文本编辑器”。

我应该从这个陈述中理解什么?

初始化数据段

据说“初始化数据段”包含全局变量和静态变量,但我还看到 const char* string = "hello world" 使字符串文字为“hello world”存放在初始化只读区,字符指针变量string存放在初始化读写区。 char* string存放的是只读区还是读写区?由于两者都写在这里,我有点困惑。

堆栈

据我了解,堆栈包含局部变量。这样对吗?

最佳答案

文本段包含程序的实际代码,即编译器发出的机器代码。最后一条语句的意思是,您的 C 程序和文本编辑器是完全一样的东西;它只是从内存中执行的机器代码指令。

例如,我们将采用以下代码,以及我现在刚刚想到的一个假设架构,因为我不记得 x86 汇编。

while(i != 10)
{
x -= 5;
i++;
}

这将转化为以下说明

LOOP_START:
CMP eax, 10 # EAX contains i. Is it 10?
JZ LOOP_END # If it's 10, exit the loop
SUB ebx, 5 # Otherwise, subtract 5 from EBX (x)
ADD eax, 1 # And add 1 to i
JMP LOOP_START # And then go to the top of the loop.

LOOP_END:
# Do something else

这些是您的处理器可以理解的低级操作。然后这些将被翻译成二进制机器代码,然后存储在内存中。实际存储的数据可能是 5、2、7、6、4、9,例如,考虑到我刚刚想到的操作和操作码之间的映射。有关这实际上是如何发生的更多信息,请查看汇编程序和机器代码之间的关系。

-- Ninja-edit - 如果你采纳 RBK 上面的评论,你可以使用 objdump 或类似的反汇编程序查看构成你的应用程序的实际指令。在 Visual Studio 的某个地方有一个,或者您可以在 Windows 上使用 OllyDbg 或 IDA。

因为程序的实际指令应该是只读的,所以不需要为程序的多次运行复制文本段,因为它应该始终相同。

至于您关于数据段的问题,char* string 实际上将存储在.bss 段中,因为它没有初始化程序。这是一个内存区域,在您的程序运行之前(通过 crt0 或等效程序)被清除,除非您给 GCC 一个我不记得的标志。 .bss段是可读写的。

是的,堆栈段包含您的局部变量。实际上,它存储所谓的“堆栈帧”。其中之一是为您调用的每个函数创建的,并且它们相互堆叠。正如您所说,它包含诸如局部变量之类的东西,以及其他有用的位,例如调用函数的地址,以及其他有用的数据,以便在函数退出时可以恢复先前的状态。对于堆栈框架中实际包含的内容,您需要深入研究架构的 ABI(应用程序二进制接口(interface))。

关于c - 关于C程序内存布局的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16815485/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com