二进制文件和操作系统有联系吗?

2023-01-19 22:41:45 +08:00
 Gav1nw
二进制文件和处理器架构有关,和操作系统呢?排除调用到特定操作系统运行库的情况,一个二进制文件可以同时在特定架构如 arm x86 等 的所有操作系统运行吗?
4284 次点击
所在节点    程序员
38 条回复
yehoshua
2023-01-20 09:48:35 +08:00
不同 CPU 平台不行,指令集都不同。二进制代码,汇编这东西,和硬件关系很大。操作系统反而影响没有硬件强。
yuezk
2023-01-20 10:29:09 +08:00
这个帖子让我想到了前段时间看到的一篇关于 Wine 的文章([How Wine works 101]( https://werat.dev/blog/how-wine-works-101/),[中文译文]( https://www.freebuf.com/articles/system/346955.html))。

实际上无论是什么操作系统,最终运行二进制文件都是 CPU 的工作,操作系统只是负责把二进制文件加载到 CPU 上去执行。而相同架构的 CPU 的指令又是一样的,所以理论上是可以把在 Windows 的编译的二进制文件移植到 Linux 上去的,

再看二进制文件,它其实是有结构的,可以简单理解成由 header 和 body 组成。header 部分是给操作系统来读取进行加载的,这部分不同的操作系统之间是有差别的。body 部分是 CPU 的指令,是真正要运行的部分,这部分的内容是和操作系统无关的。

所以可以这样理解,Wine 的主要工作是读取了二进制文件中的 body 部分,并加载到 CPU 运行。另外,它还 hook 了一些 Windows 上的系统函数,转成在的 Linux 里面的实现。

所以,理论上来说,用 Wine 运行 Windows 的程序,其性能并不会比在 Windows 中差,甚至有的时候还会更快。
yuezk
2023-01-20 10:30:23 +08:00
更新链接:How Wine works 101: https://werat.dev/blog/how-wine-works-101/
bashbot
2023-01-20 11:05:08 +08:00
可执行二进制文件,排除 jar 和 pyc 这种解释执行,单说已经汇编成为机器指令的二进制文件,其中操作系统相关的有:
操作系统内核提供的系统调用
操作系统其他库提供的函数调用
操作系统 ABI ,包括:二进制文件容器格式,二进制程序加载方式,函数参数和返回方式,等

通过精巧的设计,可以实现很多兼容性。比如
在 windows 上执行 linux 程序的 colinu
在 linux 系统执行 windows 程序的 Longene

甚至可以自定义 ABI ,然后实现各个平台的加载器,基础库,以及系统调用转发库。达到一次编译多平台运行的目的。

另外,汇编成机器指令的二进制文件直接执行是 CPU 架构相关的,如果需要跨 CPU 架构,需要考虑解释执行。
Gav1nw
2023-01-20 12:01:05 +08:00
我之前的理解只知道二进制文件和 CPU 架构的相容性,并没想过系统调用等和特定系统接口绑定的情况。之上一直做 JAVA Web 对于真正底层的工作只能说是一知半解,最近研究 ESP32 所以发出次疑惑🤔总之谢谢朋友们的解答了
Gav1nw
2023-01-20 12:01:49 +08:00
@misaka19000 谢谢🙏写的好详细
yuezk
2023-01-20 12:03:25 +08:00
@Gav1nw #4 .class 文件不是直接运行在 CPU 上的,它是运行在 JVM 上的,而 JVM 在不同的系统和 CPU 架构上有不同的实现,这对 .class 文件来说是透明的,Java 也正是靠不同平台的 JVM 实现了跨平台。
Gav1nw
2023-01-20 12:05:17 +08:00
@dcsuibian 我刚看了一下发现确实底层包的.jar 下次研究透再问
Gav1nw
2023-01-20 12:07:22 +08:00
@yuezk java 这块我还算了解,只是对 c 代码这块,我原来一直想的是编译后应该是结合 CPU 指令集的代码,没想到还有系统调用等
leimao
2023-01-20 15:27:09 +08:00
给个最简单的例子,操作系统 A 和 B ,均使用 ARM64 处理器。在操作系统 A 把程序 main.cpp build 成一个 binary C ,在操作系统 B 把同样的程序 main.cpp build 成一个 binary D 。想要运行 binary ,需要有对应的 runtime ,runtime 会读取 binary ,然后执行 binary 里面的指令。这两个程序的执行的指令是一样的,意味着 runtime 解读 binary 之后执行的指令需要一样,而不是 binary 需要一样。不同的 runtime 解读不同的 binary 也可以运行相同的指令。比方说 binary C 是 010101 ,binary D 是 101010 ,操作系统 A 的 runtime 是正着读,操作系统 B 的 runtime 是反着读,那么最终他们读的都是相同的。这也说明,理论上,通过特殊设计,是可以让同一个 binary 在同一个 CPU 的不同操作系统里运行的。
mejee
2023-01-20 15:35:14 +08:00
1 、有关系
2 、不能
n18255447846
2023-01-20 16:33:06 +08:00
参考大部分项目的编译产物,都是以[文件名]-[系统]-[架构].xxx 命名
macha
2023-01-20 16:58:29 +08:00
对于 CPU 来说都一样,但是应用程序和 CPU 之间还隔着一个操作系统。所以二进制文件和操作系统是密切相关的。
你没发现现在流行的几个操作系统都有一个对应的编译器么。
zinwalin
2023-01-20 18:42:00 +08:00
@Gav1nw 不是同一文件。
iOCZ
2023-01-20 19:04:11 +08:00
@Gav1nw Java 虚拟机敉平了平台差异,可以用相同的字节码文件
Gav1nw
2023-01-20 20:50:05 +08:00
@leimao 我对现代操作系统的理解是,负责进程调度、系统资源分配等,操作系统通过虚拟地址等,让每个进程都以为自己独占整个系统资源,所以程序不是应该对系统是无感知的吗?
irytu
2023-01-21 07:30:41 +08:00
lingling47
2023-01-22 20:36:04 +08:00
java 这不就是我嘛

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/909970

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX