【问题标题】:Where does the instruction of an executable go to?可执行文件的指令在哪里?
【发布时间】:2016-06-30 16:46:53
【问题描述】:

请不要标记为重复:我知道我们 .exe 等可执行文件是一组机器语言(二进制)指令,但我不知道这些指令是否针对系统(然后针对内核) ) 然后到 CPU 还是由 CPU 直接从内存中读取?我有点迷茫

【问题讨论】:

    标签: operating-system system-calls cpu-architecture


    【解决方案1】:

    安排可执行文件运行由进程加载器完成,通常是 UI shell 的一部分或由 UI shell 执行。

    exe文件包含头元数据和可执行代码。

    加载程序读取可执行文件头,分配一个初始工作集的内核和进程需要运行的其他资源,并创建一个线程来在进程入口点运行代码。如果该代码尚未被加载器读入内存,它现在将在立即页面跳转加载它时发生。

    然后进程存在,并且有一个线程正在运行它。

    总结:图像文件(Wondows 中的 .exe)包含供操作系统加载程序解释的元数据和可执行代码。可执行代码指令由加载器读入内存,CPU从内存中取出并执行这些指令。

    【讨论】:

    • 虽然我不知道加载器是什么(我认为它是操作系统的一部分),我不知道线程是什么,但我可以清楚地看到操作系统设置CPU通过准备内存来运行指令的表,对吗?
    • @MekacherAnis 基本上,是的:)
    【解决方案2】:

    您的问题始于一个错误。

    我知道我们.exe等可执行文件是机器语言(二进制)的一组指令

    通常,可执行文件是一组如何将程序或库加载到内存中的指令。 (有一些可执行文件作为它加载到内存中,但通常用于操作系统和嵌入式系统。)

    程序或库将包含以下数据:

    • 只读
    • 读写
    • 读写初始化为零
    • 执行

    链接器通常将程序的各个部分组织在与这些组相对应的程序段中。

    程序加载读取可执行文件中的指令并创建这些部分。对于只读数据,加载器创建适当的页面,将数据加载到其中,并将页面标记为可读写。有些系统实际上将内存页面直接映射到可执行文件,并使用可执行文件对这些部分进行分页。

    对于初始化为零段的读写,可执行文件不需要包含数据。我只需要告诉加载器创建页面并将所有内容设置为零。

    可执行文件还将定义需要加载的动态库和地址修复(需要修复的地址,取决于加载的位置)。

    如果可执行文件定义了一个程序(而不是库),它将指示程序的起始地址,以便它可以执行。

    【讨论】:

    • 所以你基本上是在说可执行文件包含如何在内存中布置其指令的信息,这些信息是特定于平台的(由链接器设置)和加载程序,它是操作系统处理它们,我是对的请回答我吗?
    • 链接器将在可执行文件的程序段中布置机器指令。可执行文件告诉如何加载这些程序部分并在必要时修复它们。
    • 这就是为什么 windows 可执行文件不能在 liunx 机器上运行的原因,因为可执行文件包含 windows 加载程序必须处理的不同类型的指令,对吗?
    • 是的。即使指令将在 windows 和 Linux 机器上执行,由于可执行格式(以及它们如何链接到其他库和系统服务),可执行文件也不兼容。
    【解决方案3】:

    一个可执行文件有一堆元数据来告诉操作系统如何将它映射到内存中,以及它需要什么库。 (其他答案很好地涵盖了这一点)。

    因此,操作系统为在此可执行文件(或该 POSIX 系统调用的 Windows 等效项)上运行 execve(2) 的进程设置了一个新的虚拟地址空间。它将可执行文件的页面映射到该虚拟地址空间,然后跳转到入口点(使用特殊的跳转指令删除内核模式权限,例如 iret 上的 sysreturn)。

    此时,CPU 正在用户空间进程中直接从内存中执行指令。该内存是磁盘上内容的副本。 (见page cache)。

    在进程进行系统调用或中断到达之前,不会运行内核代码。 (例如,计时器中断,此时内核可能会决定该进程目前已拥有其 CPU 份额,并上下文切换到不同的进程)。

    【讨论】:

    • 感谢您的解释,但我只是个菜鸟,因为我刚刚学习 C++,所以我不懂大部分词汇和操作系统的东西,所以简而言之,你的意思是什么,谢谢
    • @MekacherAnis:我的意思是 CPU 自己运行指令。在将它们提供给 CPU 的过程中,内核不涉及每条指令。
    • 好吧,这是我的总结,告诉我什么是对什么错:可执行文件包含的指令告诉 Windows 加载器它应该如何在内存中布局,所以最后这些指令首先进入操作系统所以它为 CPU 准备环境来完成他的工作,windows 还负责释放内存,作为旁注,关于它应该如何链接其他库和系统服务的说明因操作系统而异。那我说的对吗?非常感谢
    • @MekacherAnis:听起来不错。不过,您应该说“元数据”,以避免与 x86 机器指令混淆。
    • 谢谢 man m 虽然我没有研究过操作系统,但至少我知道一点,谢谢,真的很抱歉再次问,但你能用外行的话解释一下 64 位和 64 位有什么区别吗?和 32 位,谢谢
    猜你喜欢
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 2014-11-08
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    相关资源
    最近更新 更多