3

请耐心回答,因为我对这一切都不熟悉,并且希望我的基础知识 100% 正确。我是一名机械工程师,所以不要苛刻。我正在学习一些非常基本的低级内容,并且有兴趣了解与编译器后端相关的概念。C/C++ 编译器输出可能是专门为计算机体系结构量身定制的机器代码。这也意味着如果两者都运行在相同的硬件上,例如 i7 处理器,它在 Windows 和 Linux 中应该是相同的。但是二进制格式的形式还有另一层区别。也就是说,我们在 Linux 上有 ELF(Executable and Linkable Format),在 Windows 上有 PE/COFF(Portable Executable)。

因此,我觉得 Linux 和 Windows 上的编译器的后端工作方式不同,并以 ELF 或 PE/COFF 格式发出二进制文件。

ReactOS是 Windows 的克隆,并且在一定程度上与 Windows 二进制兼容。

理论上是否有可能在 ReactOS 中拥有一个能够理解 ELF 并正确加载它的 LOADER?

我知道我们需要有一层将 Linux API 映射到 ReactOS API 的软件。如果存在这样的映射层,我的问题有意义吗?

4

1 回答 1

4

装载机是不够的。

操作系统有自己的系统调用接口。我对Linux和Windows二进制API了解不多,上次我直接使用系统调用是MS-DOS。

在 MS-DOS 中,可以通过将函数代码加载到 AH 寄存器来调用 DOS 函数,然后调用 INT 21H。寄存器 AL 通常用作子功能或主要参数。例如,我可以回忆起如何退出程序:

    MOV AX,4C01H   ; funciton AH = $4C (exit), error code is AH = 1
    INT 21H
; program gets never here

因此,其他操作系统提供其他时尚界面。例如,AmigaDOS 的 exec.library 的地址位于绝对地址 4(是的,$00000004),并且可以通过位于库“基”地址(-4、-8 等)的负偏移量的跳转表来访问库函数。其他库的指针可以通过使用 open 函数从 exec.library 中查询。

好的,MS-DOS 和 AmigaDOS 在不同的体系结构上运行,但它是操作系统调用可能不同的一个很好的例子。软件中断与第一个库提供的库地址。

有时,差异是一种运气。当不同的操作系统调用不干扰时,可以编写一个wrapper,它接收外来操作系统调用,并将它们转换为宿主操作系统。如果操作系统 API 仅在系统调用的参数顺序上有所不同,那将是完美的——但情况会更加困难。更简单的函数可以映射到其他操作系统的风格,但更复杂的函数 - 带有回调!- 更难。包装器不仅可以模拟功能,还可以模拟操作系统的错误。

无论如何,这个类型有一些好东西。

一个很好的例子是CygWin,它可以让你在 Win32 下运行 Linux 程序。当我最后一次使用它时,运行任何命令行东西都没有问题,即使使用线程、网络等。编辑:它需要重新编译和库,正如@fortran 所说。

对于 Linux,WINE非常适合运行 Win32 应用程序。甚至还有使用 WINE 的商业软件的官方 Linux 版本!如果您的程序没有使用最新的 Windows API 调用,WINE 应该可以工作。

由于 Linux 和 BSD 都是与 POSIX 兼容的操作系统,因此存在像BSD 的Linux 兼容层这样的东西也就不足为奇了。

于 2013-02-04T14:22:36.600 回答