【发布时间】:2016-06-30 16:46:53
【问题描述】:
请不要标记为重复:我知道我们 .exe 等可执行文件是一组机器语言(二进制)指令,但我不知道这些指令是否针对系统(然后针对内核) ) 然后到 CPU 还是由 CPU 直接从内存中读取?我有点迷茫
【问题讨论】:
标签: operating-system system-calls cpu-architecture
请不要标记为重复:我知道我们 .exe 等可执行文件是一组机器语言(二进制)指令,但我不知道这些指令是否针对系统(然后针对内核) ) 然后到 CPU 还是由 CPU 直接从内存中读取?我有点迷茫
【问题讨论】:
标签: operating-system system-calls cpu-architecture
安排可执行文件运行由进程加载器完成,通常是 UI shell 的一部分或由 UI shell 执行。
exe文件包含头元数据和可执行代码。
加载程序读取可执行文件头,分配一个初始工作集的内核和进程需要运行的其他资源,并创建一个线程来在进程入口点运行代码。如果该代码尚未被加载器读入内存,它现在将在立即页面跳转加载它时发生。
然后进程存在,并且有一个线程正在运行它。
总结:图像文件(Wondows 中的 .exe)包含供操作系统加载程序解释的元数据和可执行代码。可执行代码指令由加载器读入内存,CPU从内存中取出并执行这些指令。
【讨论】:
您的问题始于一个错误。
我知道我们.exe等可执行文件是机器语言(二进制)的一组指令
通常,可执行文件是一组如何将程序或库加载到内存中的指令。 (有一些可执行文件作为它加载到内存中,但通常用于操作系统和嵌入式系统。)
程序或库将包含以下数据:
链接器通常将程序的各个部分组织在与这些组相对应的程序段中。
程序加载读取可执行文件中的指令并创建这些部分。对于只读数据,加载器创建适当的页面,将数据加载到其中,并将页面标记为可读写。有些系统实际上将内存页面直接映射到可执行文件,并使用可执行文件对这些部分进行分页。
对于初始化为零段的读写,可执行文件不需要包含数据。我只需要告诉加载器创建页面并将所有内容设置为零。
可执行文件还将定义需要加载的动态库和地址修复(需要修复的地址,取决于加载的位置)。
如果可执行文件定义了一个程序(而不是库),它将指示程序的起始地址,以便它可以执行。
【讨论】:
一个可执行文件有一堆元数据来告诉操作系统如何将它映射到内存中,以及它需要什么库。 (其他答案很好地涵盖了这一点)。
因此,操作系统为在此可执行文件(或该 POSIX 系统调用的 Windows 等效项)上运行 execve(2) 的进程设置了一个新的虚拟地址空间。它将可执行文件的页面映射到该虚拟地址空间,然后跳转到入口点(使用特殊的跳转指令删除内核模式权限,例如 iret 或 x86 上的 sysreturn)。
此时,CPU 正在用户空间进程中直接从内存中执行指令。该内存是磁盘上内容的副本。 (见page cache)。
在进程进行系统调用或中断到达之前,不会运行内核代码。 (例如,计时器中断,此时内核可能会决定该进程目前已拥有其 CPU 份额,并上下文切换到不同的进程)。
【讨论】: