为什么“可执行文件”是依赖操作系统?

发布于 2024-10-27 04:47:29 字数 308 浏览 6 评论 0原文

据我所知,每个 CPU/架构都有自己的指令集,因此为特定 CPU 编写的程序(二进制)无法在另一个 CPU 上运行。但我真正不明白的是为什么可执行文件(例如 .exe 之类的二进制文件)不能在 Linux 上运行,但可以在 Windows 上运行,甚至在同一台机器上。

这是一个基本问题,我期望的答案是 .exe 和其他二进制格式可能不是原始机器指令,但它们包含一些依赖于操作系统的数据。如果这是真的,那么这个依赖于操作系统的数据是什么样的?例如,.exe 文件的格式是什么以及它与 Linux 可执行文件之间的区别?

有没有来源可以让我获得有关此内容的简要和详细信息?

I understand that each CPU/architecture has it's own instruction set, therefore a program(binary) written for a specific CPU cannot run on another. But what i don't really understand is why an executable file (binary like .exe for instance) cannot run on Linux but can run on windows even on the very same machine.

This is a basic question, and the answer i'm expecting is that .exe and other binary formats are probably not Raw machine instructions but they contain some data that is operating system dependent. If this is true, then what this OS dependent data is like? and as an example what is the format of an .exe file and the difference between it and Linux executables?

Is there a source i can get brief and detailed information about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

白云不回头 2024-11-03 04:47:29

为了做一些有意义的事情,应用程序需要与操作系统进行交互。由于系统调用和用户空间基础设施在 Windows 和 Unix/Linux 上看起来根本不同,因此具有不同格式的可执行程序是最小的麻烦。需要更改的是程序逻辑

(您可能会说,如果您的程序仅依赖于标准化组件(例如 C 运行时库),那么这是毫无意义的。这在理论上是正确的 - 但与大多数应用程序无关,因为它们被迫使用依赖于操作系统的东西)。

Windows PE(EXE、DLL、..)文件和 Linux ELF 二进制文件之间的其他差异与两个操作系统的不同图像加载器和一些设计特征有关。例如,在 Linux 上,使用单独的程序来解析外部库导入,而此功能在 Windows 上内置。另一个例子:Linux 共享库的功能与 Windows 上的 DLL 不同。更不用说这两种格式都经过优化,以使各自的操作系统内核能够尽快加载程序。

像 Wine 这样的模拟器试图填补这个空白(并且实际上证明最大的问题不是二进制格式而是操作系统接口!)。

In order to do something meaningful, applications will need to interface with the OS. Since system calls and user-space infrastructure look fundamentally different on Windows and Unix/Linux, having different formats for executable programs is the smallest trouble. It's the program logic that would need to be changed.

(You might argue that this is meaningless if you have a program that solely depends on standardized components, for example the C runtime library. This is theoretically true - but irrelevant for most applications since they are forced to use OS-dependent stuff).

The other differences between Windows PE (EXE,DLL,..) files and Linux ELF binaries are related to the different image loaders and some design characteristics of both OSs. For example on Linux a separate program is used to resolve external library imports while this functionality is built-in on Windows. Another example: Linux shared libraries function differently than DLLs on Windows. Not to mention that both formats are optimized to enable the respective OS kernels to load programs as quick as possible.

Emulators like Wine try to fill the gap (and actually prove that the biggest problem is not the binary format but rather the OS interface!).

世界等同你 2024-11-03 04:47:29

.exe 和其他二进制格式[绝对]不是原始机器指令,但它们包含一些依赖于操作系统的数据。

这个依赖于操作系统的数据是什么样的?例如,.exe 文件的格式是什么以及它与 Linux 可执行文件之间的区别?

好吧,我猜谷歌让你彻底失望了。 Windows 文档对.EXE 格式进行了非常明确的定义。

http://support.microsoft.com/kb/65122

Linux ld application 在“exec”该文件之前将可执行文件加载到内存中。您可以阅读 ld 格式甚至著名的 a.out 文件。

http://linux.die.net/man/1/ld

http://en.wikipedia.org/wiki/A.out

http://en.wikipedia.org/wiki/Executable

.exe and other binary formats are [definitely] not Raw machine instructions but they contain some data that is operating system dependent.

what this OS dependent data is like? and as an example what is the format of an .exe file and the difference between it and Linux executables?

Well, I guess Google failed you utterly. .EXE formats are very well-defined by Windows documentation.

http://support.microsoft.com/kb/65122

The Linux ld application loads an executable into memory prior to "exec" to that file. You could read up on ld format or even the famous a.out file.

http://linux.die.net/man/1/ld

http://en.wikipedia.org/wiki/A.out

http://en.wikipedia.org/wiki/Executable

一曲爱恨情仇 2024-11-03 04:47:29

除了系统加载程序必须识别的可执行格式(即操作系统将可执行文件放入内存的部分)之外,真正的问题是操作系统的接口。您可以将操作系统视为一种 API,它提供执行特定操作(例如向控制台写入字符)必须调用的入口点。

这些细节通常或多或少对最终用户隐藏,因此您可以使用高级语言的相同源代码将字符写入屏幕。但通常情况下,情况会更加不同,例如窗口环境。并非所有高级语言都提供一个窗口层来抽象这些差异。

Apart from the executable format that must be recognized by the system loader (i.e. that part of an OS that brings the executable into memory) the real problem is the interface to the OS. You can think of an OS as a kind of API that provides entry points one must call for doing specific things, like for example, writing a character to the console.

These details are usually more or less hidden from the end user, so that you can achieve writing a character to the screen with the same source code in higher level languages. But often, things are more different, like for example the Windowing environment. Not all high level languages provide a windowing layer that abstracts even over those differences.

鹤舞 2024-11-03 04:47:29

我无法对 *nix 发表太多评论,但是是的,二进制文件的代码部分通常很乐意在任一环境中运行,但操作系统对二进制文件提出了某些要求。在 Windows 中,您应该阅读 PE 标头

第二部分完全取决于开发人员,很多时候代码部分将引用特定于操作系统的库 - 这就是为什么在编译成二进制文件之前可以同时拥有可移植和不可移植的 C++ 代码。

I can't comment too much on *nix but yes, the code part of the binary is typically happy to run on either environment, but it is the OS that places certain demands on the binary. In windows you should read up on PE Headers.

The second part is simply up to the developer, many times the code part will reference libaries that are OS specific - which is why you can have both portable and non-portable C++ code before being compiled into a binary.

何处潇湘 2024-11-03 04:47:29

一个非常天真的答案:

  1. 由于进程加载器不同,它们的结构也不同;
  2. 使用依赖于操作系统的功能,例如系统调用,这些功能因操作系统而异。

A very naive answer:

  1. Their structure are different because of different process loaders;
  2. The use os-dependent features like syscalls, which vary from OS to OS.
¢好甜 2024-11-03 04:47:29

程序需要知道如何调用操作系统服务。如何完成此操作取决于操作系统:有些使用中断,有些使用 x86 lcall 指令,有些(尤其是 Windows)具有区分的共享库,并且不记录如何直接调用服务。旧的 680x0 Mac 和其他一些 680x0 操作系统使用保留的指令集区域并捕获由此产生的“无效 CPU 操作码”异常。此外,即使机制相同,系统调用的顺序和参数格式也会因操作系统而异(有时同一操作系统的不同版本;请参阅 Linux 内核中的 stat())已更改多次的界面示例)。

有一些处理其他操作系统约定的能力:FreeBSD 有“linuxulator”来处理 Linux 特定的内核接口,NetBSD 类似地有用于其他操作系统的系统调用格式的模拟器,使用相同的硬件(例如,MIPS 上的 Ultrix 或 Alpha 上的 OSF/1),Linux 过去使用 iBCS2 来处理 UnixWare/SCO Unix 内核接口,Wine 为 PE 风格的 Windows 可执行文件提供替换共享库和二进制加载器。 (我不记得 Wine 是否也支持 OS/2 风格的 LX .exe;它可能确实处理原始格式 .exe;然后还有 . com 这是一个带有标头的原始内存转储。)即便如此,总有一些格式使用不同的约定,有时这些约定足够相似,需要操作系统提示如何处理它。 (例如,请参阅 FreeBSD 上的 bless。)

Programs need to know how to invoke operating system services. How this is done depends on the operating system: some use interrupts, some use the x86 lcall instruction, some (notably Windows) have distinguished shared libraries and don't document how to directly invoke services. Old 680x0 Macs and some other 680x0 operating systems used a reserved instruction set area and trapped the resulting "invalid CPU opcode" exception. Moreover, even when the mechanism is the same, the order and argument format of system calls differs between operating systems (and sometimes different versions of the same operating system; see stat() in the Linux kernel for an example of an interface that has changed several times).

There is some ability to deal with other operating systems' conventions: FreeBSD has the "linuxulator" which handles the Linux-specific kernel interface, NetBSD similarly has emulators for the system call formats of other operating systems using the same hardware (say, Ultrix on MIPS or OSF/1 on Alpha), Linux used to have iBCS2 to handle the UnixWare/SCO Unix kernel interface, Wine provides replacement shared libraries and a binary loader for PE-style Windows executables. (I don't recall if Wine also supports OS/2-style LX .exes; it probably does handle original format .exe; and then there's .com which is a raw memory dump with a header slapped on.) Even so, there is always some format that uses different conventions, and sometimes the conventions are similar enough to require hints to the OS as to how to deal with it. (See bless on FreeBSD, for example.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文