程序的内存布局中“内核堆栈”、“C 运行时启动函数的框架”和“main() 的框架”在哪里?

程序的内存布局中“内核堆栈”、“C 运行时启动函数的框架”和“main() 的框架”在哪里?

来自 Linux 编程接口:

在此输入图像描述

  1. 上图中内核堆栈(在下面的引用中提到)在哪里?

    它是上图中上面的部分“内核(映射到进程虚拟内存,但没有访问程序)”吗?

    期限 用户栈 用于区分我们这里描述的堆栈和内核堆栈。内核堆栈是在内核内存中维护的每个进程的内存区域,用作执行系统调用期间内部调用的函数的堆栈。 (内核不能为此目的使用用户堆栈,因为它驻留在不受保护的用户内存中。)

  2. 上图中“C 运行时启动函数的框架”和“main() 的框架”(下图中提到的)在哪里?

    上图中的“argv,environ”是“C 运行时启动函数的框架”、“main() 的框架”还是两者的一部分?

    在此输入图像描述

  3. 0x00000000 和 0x08048000 之间的最低段有何用途?

谢谢。

答案1

  1. 那没有A内核堆栈。对于每个线程,都有一个内存区域,当进程进行系统调用时,该区域用作堆栈空间。还有单独的“中断堆栈”,每个 CPU 一个,由中断处理程序使用。这些内存区域驻留在内核地址空间中(上0xc0000000图所示)。

  2. 堆栈框架(C 运行时框架、main 框架等)是堆栈的一部分。进程参数 ( argv) 和环境是单独的区域,并且不是堆栈的一部分。

  3. 0x0和之间的区域0x08048000(大约 128 MB)没有用于任何用途。最初,i386 System V ABI 为堆栈保留了这个区域,但 Linux 的做法有所不同。不使用该区域不会浪费 RAM,只会浪费地址空间,因为该区域没有被映射。请注意,此信息现在几乎完全过时,因为它描述了如何在 32 位 x86 架构上完成操作。如今,仅 32 位的 x86 机器很难找到,并且发行版正在逐步取消对它们的支持。

答案2

引用自csapp第三名第9章:

在此输入图像描述

内核虚拟内存的其他区域包含每个进程不同的数据。示例包括页表、内核在进程上下文中执行代码时使用的堆栈,以及跟踪虚拟地址空间当前组织的各种数据结构。

我相信每个进程都有内核堆栈。至少对于执行系统调用来说,这可能会调用需要以管理员权限存储数据的内核内部函数。也适用于内核中断处理程序。

有关的答案

  1. 每个进程都有自己的内核堆栈吗?

不仅仅是每个进程 - 每个线程都有自己的内核堆栈(实际上,还有自己的用户堆栈)。请记住,进程和线程(对于 Linux)的唯一区别是多个线程可以共享地址空间(形成进程)。

相关内容