为什么可执行文件OS依赖?

时间:2017-02-13 09:48:15

标签: operating-system

我见过很多人都在问这个问题,而且我看到的答案大多是这样的:“因为操作系统有不同的API”。我不明白这一点,因为当代码编译成机器指令时。为什么API只是对CPU的指令而言才更重要?假设我使用Windows API中的CreateWindow函数。然后将CreateWindow转换为CPU的机器代码。那么为什么它不能在Linux上运行呢?另一个操作系统如何知道我使用的是Windows API,因为它现在是机器指令。请解释一下。

2 个答案:

答案 0 :(得分:1)

  

为什么API只是对CPU的指令而言才重要?

因为不是只是CPU的指令。

  

假设我使用Windows API中的CreateWindow函数。然后将CreateWindow转换为CPU的机器代码。

调用编译为机器代码,是的。但是该代码只是调用Windows提供的函数,而不是嵌入在代码中。由于Linux没有相同的CreateWindow函数,因此您的代码将无法在Linux上运行。

不同操作系统的可执行文件也有不同的格式。它们不仅仅是从第一个字节开始运行的代码块。它们具有(略微)复杂的结构,特定于目标OS的体系结构,因此操作系统知道如何从文件加载代码,将其链接到需要链接到的特定于操作系统的东西(如DLL提供CreateWindow),将其代码映射到代码区域,将其数据映射到数据区域等。

简而言之:

  • 您的可执行文件不是一个独立的代码块,其中包含所有需要运行的代码;它链接到操作系统提供的资源
  • 可执行文件格式因操作系统而异

答案 1 :(得分:0)

假设底层处理器是相同的,那么您要求的通用兼容性类型存在几个主要问题。所有程序都会在某个时间调用操作系统服务。我不认为Windoze CreateWindow函数是一个真正的系统服务,但我们假设它是(如果不是,它显然至少调用一个真正的系统服务,可能是几个)。系统服务被编写为包装和解包硬件寄存器的包装器

在该包装器中(这里是一个粗略的简化),实际的系统调用被调用类似

CHANGEMODETOKERNELINSTRUCTION #SERVICENUMBER

更改模式指令触发异常,导致处理器调用操作系统定义的内核模式异常处理程序。操作系统处理程序按编号跳转到特定的系统服务。

如果Eunuchs系统服务号码与Windoze系统服务号码不匹配(由于他们有不同的系统服务,他们永远不会这样做),您的程序不能有相同的行为。