昨天复习《深入理解计算机系统》,参考了小土刀的博客,看到了进程和程序在内存中是如何组织的,虽然这张图看了很多遍但是总感觉有疑问。努力解决,参考《深入理解计算机系统》。
图1 C程序的编译过程
如上图一个 C 语言程序需要经过预处理、编译器、汇编器、链接器 才可以生成一个可执行文件(程序)。
hello.s 汇编代码使用汇编器生成可重定位目标文件 hello.o。
hello.o 和它 引入的类库 printf.o 使用链接器生成可执行程序。下图可执行文件的存储格式示例
当在 Shell 实行 ./hello 时,Shell 认为 hello 是一个可执行文件,于是调用驻留在存储器中称为加载器(loader)的操作系统代码来运行它。 加载器将可执行目标文件的代码和数据从磁盘读到内存,然后通过跳转到程序的第一条指令或者入口点来运行程序。
shell 执行一个程序时,父 shell 进程生成一个子进程,他是父进程的一个复制。子进程通过 execve 系统调用加载器。加载器删除子进程的虚拟内存段,并创建新的代码、数据、堆和栈段。通过将虚拟地址的页地址映射到内存中可执行文件的页地址来初始化可执行文件的内容。最后,加载器跳转到 _start 地址,调用程序的 main 函数。
通过上面的描述可以理解到为什么 “程序总是运行在某个进程的上下文中”。
了解了可执行文件的存储格式,加载一个可执行文件到初始化一个进程,但是总感觉有很多疑惑没有解开、理解也可能不正确.......