【发布时间】:2013-04-24 06:32:06
【问题描述】:
让我们考虑一个在 Windows 中编译的简单 C 程序。
我可以在 Intel CPU 机器上编译程序并在 AMD CPU 机器上运行它(相同的操作系统)。那么是不是说明CPU的指令集是一样的呢?
为什么同一个程序不能在不同操作系统和相同 CPU 的机器上运行?
【问题讨论】:
标签: operating-system hardware computer-architecture
让我们考虑一个在 Windows 中编译的简单 C 程序。
我可以在 Intel CPU 机器上编译程序并在 AMD CPU 机器上运行它(相同的操作系统)。那么是不是说明CPU的指令集是一样的呢?
为什么同一个程序不能在不同操作系统和相同 CPU 的机器上运行?
【问题讨论】:
标签: operating-system hardware computer-architecture
目标文件的二进制设置完全不同。还有哪些库可用或如何调用它们。
只需比较 ELF 或 EXE 文件的标头即可了解我的意思。
如果你编写一个像 "main(){printf("Hello\n"); return 0;} 这样的简单程序,那么编译器会在后台执行很多操作来打印这些行。运行在同一个 CPU 上没有帮助,因为它可以执行汇编指令,但是一旦调用第一个 OS 函数就会严重失败。
详细说明一下:
作为一个例子。假设我们在 Amiga OS 上运行,带有 Motorola 68000 CPU。
如果我没记错的话,调用系统库的调用约定涉及将指针加载到 CPU 的地址寄存器中,然后调用 OS 函数。
现在假设我也使用摩托罗拉 68000 CPU 编写自己的操作系统。然而,当我设计我的操作系统时,我认为使用堆栈进行数据交换是一个更好的主意,所以当你在我自己的私有操作系统中调用类似的函数时,你不会传递地址寄存器中的地址,而是你把它推到堆栈上。 现在,当您的可执行文件将在我的操作系统中执行时(假设它可以加载,因为我使用相同的对象结构)您的可执行文件会将值放入寄存器中,而我的操作系统会尝试将它们从堆栈中弹出,因为它不知道它正在寻找的值应该是其他的。
我希望这更详细一点,以便您理解它,但当然问题比这更深,因为这只是所涉及问题的一小部分。
【讨论】:
您的 Intel 和 AMD 都使用 x86(或 x86-64)架构。这就是为什么您可以在两者上运行相同的软件的原因。然而,编译后的程序不仅包含对架构的依赖,还包含对底层操作系统的依赖。即使是 Linux 可执行文件的二进制格式也与 Windows 不同。
但是,您可以使用一个使用 C 标准库的简单 C 程序,并在不同的操作系统和处理器架构上编译它。只要您的代码不包含依赖于操作系统的代码,它就会跨操作系统移植。同样,如果您的代码不依赖于底层架构字节序,例如,它将跨架构移植。
约翰。
【讨论】: