堆、栈和数据段是否在同一个汇编程序中?

7
据我所知,汇编程序分为两部分:1)代码 2)数据。 现在,当我们使用C\ C ++进行编码时,代码被加载到内存中,然后CPU开始执行代码,逐个指令地作为汇编程序。 我的问题是: 1. C代码存储在哪里?我的意思是,当我在Visual Studio中运行程序时,代码是否加载到其中一个堆栈或堆等中? 2. 因此,内存在虚拟上分为堆栈、堆和数据段,但是当CPU将程序作为汇编程序执行时,它们是否都是具有相同数据区域的一个汇编程序,还是组成了2或3个汇编程序,它们从一个跳转到另一个?
** 让我添加这个问题,也许它会澄清我的意图: 当我启动C程序时,代码(机器指令)被加载到内存中。因此,这是一个汇编程序。但是内存如何划分?我的意思是,不同的内存部分(例如堆栈、数据段等)如何修改汇编程序?
2个回答

8

来自维基百科:

PC架构支持程序中的几个基本读写内存区域,即堆栈、数据和代码。堆是程序可用的另一个地址空间区域,操作系统可以通过诸如malloc和free等系统调用动态分配或释放内存。

我建议您阅读完整文章

还有这个问题在SO上: 堆、栈、文本等不同段与物理内存有什么关系?

此外,这些文章也值得一读。特别是最后一篇:

回答您的问题:

1. c 代码存储在哪里?

存储在代码段中。

2. 因此,内存被虚拟地划分为堆栈、堆和数据段,

在实模式下,是的。在保护模式下...取决于情况。简单来说:程序内存映射到物理内存。每个程序都有自己的地址空间。

如果您想了解更多信息,我建议阅读以下文章:

3. 但是当CPU执行程序时,作为汇编程序,它们是否都是具有相同数据区域的一个汇编程序,还是它们被组成了2或3个汇编程序,跳转到另一个程序中?

不是的。没有跳转。处理器寄存器指向要执行的下一条指令。其他指向栈等。


谢谢,但这不完全是我要问的。 - izac89
@user2162550 这个更新对你有用吗?如果不是,你还需要什么额外的信息呢?为了理解基础知识,最好保持在实模式下的内存映射。这样事情会更简单。 - Jean
不是的。没有跳跃。处理器寄存器指向下一个要执行的指令。其他寄存器指向堆栈等。如果有其他寄存器指向堆栈等,那么就会有不同的汇编程序,CPU确实会从一个程序跳转到另一个程序,这是正确的吗? - izac89
1
@user2162550 没有跳跃。假设是x86 CPU:从CPU的角度来看,有指令需要执行。CPU有寄存器指向下一个要执行的指令(IP),寄存器指向堆栈(BP,SP)。CPU使用这些寄存器来获取指令流并在每个callreturn指令上将信息放入堆栈中。请参见此文章,特别是称为RegistersSegmented addressing的部分。您对哪种CPU感兴趣?x86?ARM?PPC?等等... - Jean
1
此外,在某些CPU上,使用的内存模型是段:偏移量。但这只是处理内存的一种方式。CPU实际上并不会从堆栈跳转到代码段再返回堆栈。它会从指令指针指向的内存位置加载指令,并在需要时(例如调用时,当您推送寄存器等)将数据添加到堆栈(由其他寄存器指向),或者将它们删除(弹出等)。当CPU遇到特定指令(跳转系列或调用系列)时,会发生跳转。 - Jean

7
“段”或“部分”是对象文件和可执行文件中的连续分区,就像书籍中的章节一样。堆栈和bss部分不存在于文件中,但在运行时创建。
“部分”的重点主要是将程序划分为操作系统可以以不同方式保护的区域。为了实现这一点,“部分”必须从页面边界开始,并在内存中连续存在。
基本的(“重要的”)部分是...
文本或代码 - 操作系统将对此部分进行写入保护,并且由于它是不变的,因此还可以在运行相同可执行文件的多个进程或线程之间共享。
数据 - 操作系统将映射此r / w并且不会直接共享它
bss - 此部分包含零初始化数据。
堆栈 - 通常与程序分开,一般从较高地址向下增长
最后两个部分不在可执行文件中,因为它们不需要任何初始化。
如果您想了解它们如何实现,那么汇编器和链接器将创建目录并像书籍中的章节一样以二进制形式输出部分。然后,操作系统单独读取它们并将它们放在地址空间的不同部分。
Unix类系统和Windows之间的具体细节和术语不同,但原理相同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接