你把WINDOWS程序复制到MAC上使用,会发现无法运行。你可能会说,MAC是arm处理器,而WINDWOS是X86 处理器。但是在2019年,那时候MAC电脑还全是Intel处理器,在同样的X86芯片上,运行MAC和WINDOWS 程序还是无法互相兼容。如果我们深入思考,这应该让我们感到困惑,因为可执行文件本质上是对于CPU的机器码。那问题就是:
为什么都是机器码,而不能迁移?
应用程序为何特定于操作系统的原因。即使两个操作系统使用相同的 CPU 架构,应用程序也可能无法在两个系统上运行。这是因为应用程序不仅与架构相关,还与操作系统相关。这是一个非常重要的结论,它告诉我们,虽然应用程序理论上是直接对于CPU的机器码,但是实际上受到在CPU上运行的操作系统的节制。那我们的程序,在什么时候,执行什么任务的时候,会和操纵系统相关呢?答案是系统调用(SYSTEM CALLS)的时候(聪明的同学可能已经明白怎么回事了,此事在LC3 TRAP陷入程序中亦有记载)就是
应用程序机器码 = 架构机器码 + 操作系统调用机器码 应用程序机器码=架构机器码+操作系统调用机器码 应用程序机器码=架构机器码+操作系统调用机器码
CPU 工作模式
CPU在现代计算系统中如此重要,如此处于关键地位。所有的程序的执行都要依赖它,这也意味着那些愚笨的程序员,或则恶意的程序员写的代码,如果也一字不落的执行,会对整个计算机系统造成重大危害。所以CPU有两种工作模式: 内核模式(KERNAL MODE) 和 用户模式(USERMODE)
在内核模式的时候,CPU被赋予了超级权限,它可以执行指令集中的全部内容。这样他可以完成如下功能:IO,操作计时器,读取内存。 (诸如此类的硬件操作)
而用户模式之下,CPU只会执行它的指令集的子集。完成基本的数据移动,复制,条件和循环。这些指令很有用,但是在很多时候不能满足和硬件交互的需求。
你或许已经明白操作系统工作在内核模式,而普通的应用程序工作在用户模式。
当普通的应用程序需要和硬件进行交互的时候。就会调用操作系统提供的接口。即操作系统调用。这个时候CPU的工作模式就会从用户模式转换为内核模式。将那些比较危险的操作(内存泄漏之类的啊嗯)代有操作系统完成。
操作系统的特殊接口
可以想见,操作系统通过系统调用提供服务,而这些系统调用通常是特定于操作系统的。所以应用程序基本都是特定于操作系统的。此外,可执行文件的格式也是引发兼容性问题的一个重要因素。操作系统对程序的结构和加载方式有特定的规则,以确保可执行文件的正确运行。此外,运行时环境也是影响因素之一某些编程语言在虚拟机或解释器上运行,使得代码能够跨平台运行。然而,这也带来了兼容性问题。
还有一个重要的原因,就是可执行文件格式,程序不光包含机器码,还有数据(比如运行时需要展示的字符串,图片,音频什么的)不同的操作系统把这些资源和机器码的打包方式和读取方式是不一样的,LINUX使用ELF(可连接和可执行文件格式)WINDOWS使用的PE格式(便携式可执行文件格式)。这也是一大因素,不过,不是我们今天讲的主要内容。