为什么机器代码取决于操作系统类型?

时间:2016-12-14 23:25:28

标签: c assembly compilation linker machine-code

假设我有一个用C编写的程序,我有两台相同的计算机,一台运行Windows,另一台运行Linux。由于计算机是相同的,它们的处理器具有相同的指令集,因此编译后的机器代码应该相同。那么为什么我需要两次编译我的程序呢?假设,我不会调用任何与OS相关的函数,或者取决于实际操作系统的东西。

1 个答案:

答案 0 :(得分:6)

机器代码不依赖于操作系统,对同一个CPU也是如此。

如果您使用OS不可知的机器代码,在目标CPU模式下(让我们说x86 32b),并将其加载到某些ROM内存中,那么它将可用,您可以映射该部分ROM在Windows和Linux中(通过完全不同的OS API来映射物理内存并赋予它可执行权限),并跳转到那里..并且ROM中的机器代码将以相同的方式运行。

  

那为什么我需要两次编译我的程序?假设,我不会调用任何与OS相关的函数,或者取决于实际操作系统的东西。

你不必。但通常你需要一些入口点进入你的代码,通常最简单的方法是如何提供通用入口点是遵循操作系统定义的ABI(应用程序二进制接口),所以例如在32b窗口中你从堆栈中读取参数,在64b中linux你在寄存器中接收参数(如果可能的话)。如果您不能调整您的程序序言代码以正确的方式选择参数,它将在"其他"中使用错误的输入操作。操作系统比它写的。

但是机器代码本身,CPU指令是相同的。

也就是说,在x86上,由于历史向后兼容性,情况有点多毛,因此CPU可以处于16b模式,32b [受保护]模式(其中一对加上不同的设置)或64b模式。 80386 CPU指令mov eax,1对16b模式和32b模式具有不同的机器代码编码。

但只要您的目标是相同的CPU模式,相同指令的机器代码就会以相同的方式编译。您只需按照不同的ABI来编写源代码。

可执行文件......每种格式都不同,它甚至不是每个操作系统"再次由于历史原因,几乎所有x86操作系统都支持多种可执行文件格式,因此元存储在文件中的机器代码周围的数据(在将机器代码加载到内存中并将其设置为运行时由OS使用)完全不同。

实际的例子是linux app wine,它可以执行Windows可执行文件,通过提供假的OS挂钩点来模拟Windows操作系统,以及了解Windows可执行文件二进制文件,从而正确地将它们加载到内存中。这种Windows应用程序的机器代码是本机运行的,无需进一步修补。