编程语言是如何转换为机器码的
Source: Dev.to
Introduction
编程让我们能够构建计算器、网站、AI 代理等。然而,机器并不能直接理解高级编程语言;它们只能理解二进制代码(0 和 1)。因此,每种语言在执行前都必须经过编译或解释。
Why Binaries Differ Across Platforms
-
CPU 架构 – 每种 CPU 有自己的指令集。
- Intel/AMD: x86 / x86‑64
- Apple M1/M2: ARM64
- 许多 Android 设备: ARM
-
操作系统 – 即使在相同的 CPU 上,Windows、macOS 和 Linux 也提供不同的系统 API 和库格式。
Consequences
- 为 Intel x86 CPU 编译的 Windows 可执行文件在使用 ARM CPU 的 Mac 上无法运行。
- 调用 Windows‑特定 API(例如
CreateFile())的 Windows 程序在 macOS 或 Linux 上无法运行,因为它们使用open()。 - 库格式不同:Windows 使用
.dll,macOS 使用.dylib,Linux 使用.so。Windows 的.exe无法在 macOS 上定位所需的库。
Analogy
把一份用英文写成、且只引用 Windows 厨房里工具的食谱交给 Mac 厨房的厨师会失败,因为:
- 步骤使用了不同的“语言”(CPU 指令不匹配)。
- 所需的工具不存在(操作系统系统调用不匹配)。
- 配料的存放方式不同(库不匹配)。
因此,程序必须针对每个目标平台单独编译。
Compilation Strategies
Direct Compilation
| Languages | Output |
|---|---|
| C, C++, Rust, Go | Machine code for a specific CPU + OS |
Flow: Source Code → Compiler → Machine Code (Windows / macOS / Linux)
- Pros: 执行速度最快。
- Cons: 每个平台都需要单独的二进制文件。
Bytecode + Virtual Machine
| Languages | Output |
|---|---|
| Java, Kotlin, C#, Python | Bytecode → VM → Machine Code |
Flow: Source → Bytecode → Virtual Machine (VM) → Machine Code
- Pros: 在任何拥有兼容 VM 的操作系统上都能运行。
- Cons: 相比本地代码略慢。
Interpreted + JIT
| Languages | Output |
|---|---|
| JavaScript, Python (PyPy), Ruby | Interpreter/JIT → Machine Code |
Flow: Source → Interpreter/JIT → Machine Code
- JIT(即时编译)相较于纯解释提升了性能。
Transpiled
| Languages | Output |
|---|---|
| TypeScript, Elm | Transpile → JavaScript → JIT → Machine Code |
Flow: Source → Transpiler → Target Language (e.g., JavaScript) → JIT → Machine Code
Key Takeaway
我们用人类友好的语言编写代码,但 CPU 和操作系统只能理解各自的二进制“方言”。编译器、解释器、虚拟机和 JIT 引擎把我们的代码翻译成机器能够执行的形式。