可执行文件的指令去哪里了?
Where does the instruction of an executable go to?
请不要标记为重复:我知道 .exe 等可执行文件是一组机器语言指令(二进制),但我不知道这些指令是否针对系统(然后内核)然后到 CPU 还是直接由 CPU 从内存中读取?我有点困惑
将可执行文件安排到 运行 是由进程加载程序完成的,通常是 UI shell.
的一部分或由其执行
exe 文件包含 header 元数据和可执行代码。
加载程序读取可执行文件 header,分配内核的初始工作集和进程需要的其他资源 运行 并创建一个线程 运行 代码位于进程入口点。如果该代码尚未被加载程序读入内存,它会立即发生在加载它的页面中。
然后进程就存在了,一个线程正在运行连接它。
摘要:图像文件(Wondows 中的 .exe)包含供 OS 加载器解释的元数据和可执行代码。可执行代码指令由加载程序读入内存,CPU 从内存中获取并执行这些指令。
你的问题开头有误。
I know that executable files such us .exe are a set of instructions in machine language (binary)
通常,可执行文件是一组指令,说明如何将程序或库加载到内存中。 (有一些可执行文件被加载到内存中,但那些通常用于操作系统和嵌入式系统。)
程序或库的数据是:
- 只读
- 读写
- 读写初始化为零
- 执行
链接器通常将程序的各个部分组织在与这些组相对应的程序段中。
程序加载读取可执行文件中的指令并创建这些部分。对于只读数据,加载程序创建适当的页面,将数据加载到其中,并将页面标记为读写。有些系统实际上将内存页面直接映射到可执行文件,并使用可执行文件对这些部分进行分页。
对于初始化为零的读写部分,可执行文件不需要包含数据。我只需要告诉加载程序创建页面并将所有内容设置为零。
可执行文件还将定义需要加载的动态库和地址修复(需要修复的地址,具体取决于加载的位置)。
如果可执行文件定义了一个程序(而不是一个库),它将指示程序的起始地址,以便它可以执行。
一个可执行文件有一堆元数据来告诉 OS 如何将它映射到内存,以及它需要什么库。 (其他答案很好地涵盖了这一点)。
因此 OS 为 运行 execve(2)
在此可执行文件(或 Windows 等同于POSIX 系统调用)。它将可执行文件的页面映射到该虚拟地址 space,然后跳转到入口点(使用一个特殊的跳转指令来降低内核模式特权,如 iret
或 sysreturn
on x86).
此时,CPU 正在直接从 user-space 进程的内存中执行指令。该内存是磁盘上内容的副本。 (参见 page cache)。
在进程进行系统调用或中断到达之前,内核代码不会运行。 (例如,定时器中断,此时内核可能会决定该进程暂时拥有它的 CPU 份额,然后上下文切换到另一个进程)。
请不要标记为重复:我知道 .exe 等可执行文件是一组机器语言指令(二进制),但我不知道这些指令是否针对系统(然后内核)然后到 CPU 还是直接由 CPU 从内存中读取?我有点困惑
将可执行文件安排到 运行 是由进程加载程序完成的,通常是 UI shell.
的一部分或由其执行exe 文件包含 header 元数据和可执行代码。
加载程序读取可执行文件 header,分配内核的初始工作集和进程需要的其他资源 运行 并创建一个线程 运行 代码位于进程入口点。如果该代码尚未被加载程序读入内存,它会立即发生在加载它的页面中。
然后进程就存在了,一个线程正在运行连接它。
摘要:图像文件(Wondows 中的 .exe)包含供 OS 加载器解释的元数据和可执行代码。可执行代码指令由加载程序读入内存,CPU 从内存中获取并执行这些指令。
你的问题开头有误。
I know that executable files such us .exe are a set of instructions in machine language (binary)
通常,可执行文件是一组指令,说明如何将程序或库加载到内存中。 (有一些可执行文件被加载到内存中,但那些通常用于操作系统和嵌入式系统。)
程序或库的数据是:
- 只读
- 读写
- 读写初始化为零
- 执行
链接器通常将程序的各个部分组织在与这些组相对应的程序段中。
程序加载读取可执行文件中的指令并创建这些部分。对于只读数据,加载程序创建适当的页面,将数据加载到其中,并将页面标记为读写。有些系统实际上将内存页面直接映射到可执行文件,并使用可执行文件对这些部分进行分页。
对于初始化为零的读写部分,可执行文件不需要包含数据。我只需要告诉加载程序创建页面并将所有内容设置为零。
可执行文件还将定义需要加载的动态库和地址修复(需要修复的地址,具体取决于加载的位置)。
如果可执行文件定义了一个程序(而不是一个库),它将指示程序的起始地址,以便它可以执行。
一个可执行文件有一堆元数据来告诉 OS 如何将它映射到内存,以及它需要什么库。 (其他答案很好地涵盖了这一点)。
因此 OS 为 运行 execve(2)
在此可执行文件(或 Windows 等同于POSIX 系统调用)。它将可执行文件的页面映射到该虚拟地址 space,然后跳转到入口点(使用一个特殊的跳转指令来降低内核模式特权,如 iret
或 sysreturn
on x86).
此时,CPU 正在直接从 user-space 进程的内存中执行指令。该内存是磁盘上内容的副本。 (参见 page cache)。
在进程进行系统调用或中断到达之前,内核代码不会运行。 (例如,定时器中断,此时内核可能会决定该进程暂时拥有它的 CPU 份额,然后上下文切换到另一个进程)。