我无法直接在我的硬件上启动 Windows 3.1(顺便说一句,我实际上并不是要启动 Windows 3.1,它只是作为一个例子,所以不要针对如何启动 Windows 3.1 来定制您的回答)因为当时为 CPU 编写/编译/汇编的机器代码与我的 CPU 所具有的操作码不同。
因此唯一的选择是模拟系统所需的 CPU。
但是,如果我想充分利用我的系统(例如,为这个操作系统使用全部内存),那么这种方法就行不通了。那么我宁愿在裸机上运行它。但是如果它不支持我的系统怎么办?
我不知道这是否是现实,但是否存在“适用于操作系统的编译器”?这是我的问题。
关于澄清和细节,我所说的“编译器,但操作系统”是一种接受的软件操作系统的机器代码,和操作系统所运行的硬件信息, 和即将启动的计算机的硬件信息并智能地创建操作系统的新机器代码,除非您可以在硬件/CPU 上本地启动它(显然,必须更改对原始代码的大量修改和添加,这就是我提到它“智能”的原因,就像 G++ 编译器一样)。换句话说,如果普通虚拟机所做的是解释操作系统操作码并运行等效的主机操作码,那么我所描述的只是“预先解释它”。
答案1
是否存在“编译器,但用于操作系统”这样的东西?
如果你所拥有的只是“操作系统的机器代码“,那么我假设您指的是内核的可执行二进制映像。
理论上,一个 CPU 的机器代码可以转换为不同架构 CPU 的机器代码。但这通常需要将可执行文件反汇编(即从机器代码反向转换)为汇编语言。反汇编通过使用符号标签(而不是机器代码中使用的数字内存地址)来简化分支、调用和变量的(内存)地址处理。
可执行二进制映像的反汇编很复杂,因为需要区分数据和代码。此类二进制文件的组织或布局取决于机器和编译器。
即使您设法将机器代码翻译到另一台机器上,您仍然会使用原始系统的代码实现程序。内核的可执行二进制映像包含专门为某种硬件编写的控制序列。控制和访问该硬件(例如特定外围设备)的步骤包含在该代码中。对于其他硬件系统,没有自动翻译或转换此类程序的功能。将内核代码适配到不同的机器/架构需要太多细微差别,因此必须手动完成。
目前尚无任何机制能够“智能创建新的机器代码“ 为你。
附录
他们从驱动器获得这些指令。
(传统数字计算机的)CPU 从程序计数器寄存器(又称指令指针)指定的位置获取(下一个)指令。该位置将是内存地址。
指令是从(主)内存中获取的,而不是“从驱动器“。
看运行没有内存的计算机?
我的想法是预先翻译所有代码,而不是像我认为虚拟化软件那样实时翻译。
[您似乎混淆了虚拟化和仿真。了解两者的区别。请参阅 https://stackoverflow.com/questions/6044978/full-emulation-vs-full-virtualization 。]
仿真通过可执行文件执行实际的执行路径。可执行映像始终具有起始地址,即要执行的第一条指令(机器代码)的位置。除非“执行”了分支、调用或返回指令,或者处理了中断,否则将访问后续指令的顺序位置。
执行(本机或模拟 CPU)映像可方便地识别指令和数据的位置。执行这些位置时,将以指令形式访问这些位置。当指令操作数或通过寄存器间接引用这些位置时,将访问这些位置以获取数据。
但模拟可能只会“执行”整个可执行映像中的一部分位置。将有许多位置从未被引用或访问过,因此无法确定这些位置是否包含指令或数据。识别每个位置的使用情况的任务可能非常繁琐和复杂。
是否有任何保证确保没有自修改代码?
是否有任何保证确保代码中没有混入隐藏数据,反之亦然?
将操作码转换为另一指令集通常很简单。但识别可执行映像中的每条指令与数据并不总是可靠的,尤其是当指令长度可变时(例如 Intel x86 指令)。
翻译指令集只是翻译可执行映像的第一个问题。翻译指令集仅代表 CPU 的变化。CPU 之外是系统总线和外设。代码将如何“翻译”以针对这个不同的系统执行不同的程序?
如果可执行文件是给定操作系统的用户空间程序,则硬件细节由操作系统抽象。这样的可执行文件除了 CPU 之外,对硬件的依赖性最小,转换过程也大大简化。
但由于您指定可执行文件是操作系统(我将其解释为内核),因此这就是应该实现该硬件抽象的代码。这样的可执行文件除了 CPU 之外,还具有许多硬件依赖性,转换过程非常复杂。