- 匯編的誕生
- 匯編全景圖
- 核心主干: CPU架構
- 主要分支: 語法和工具
- 共同的地貌: 核心概念
- 延伸: 跨平臺 & 跨架構
- 跨平臺
- 跨架構
- 總結
- 以 GAS vs. NASM 為例
- NASM 不支持跨架構 ≠ 無法在ARM架構上的系統安裝
匯編的誕生
- 機器語言的困境
- 早期的程序員直接使用機器語言進行編程
- 機器語言由純粹的數字(0, 1) 組成, 對應著CPU可以直接執行的指令和數據
- 繁瑣, 反人類, 難以記憶
- 匯編語言的誕生
- 為了解決上述問題, 人們發明了匯編語言(Assembly Language)
- 核心思想: 為那些晦澀的二進制機器指令起一個簡單易記的英文縮寫, 助記符(Mnemonic)
- 例如:
- ADD 代表 加法 操作
- MOV 代表 移動 數據
- 10110000 01100001 -> MOV AL, 97 大大提高編程效率和可讀性
- 匯編器的作用
- CPU只能理解二進制機器碼, 看不懂 MOV AL, 97 這樣的指令
- 匯編器被創造: 將匯編語言寫的源代碼匯編(翻譯)成機器語言目標代碼
匯編全景圖
核心主干: CPU架構
匯編語言不是一種標準化的語言, 不同的CPU架構有不同的指令集, 因此有完全不同的匯編語言.
- x86/x86-64 (CISC 復雜指令集)
- 領地: Windows, Linux.
- 特點: 歷史悠久, 指令集龐大且復雜, 變長指令, 寄存器數量小但功能強大
- 廠商: Inter 和 AMD 自行設計, 制造和銷售芯片
- ARM (RISC 精簡指令集)
- 領地: 智能手機, 嵌入式設備, 物聯網. 今年來憑借 Apple M系列芯片進入桌面領域
- 特點: 設計簡潔, 指令定長, 寄存器數量多, 采用 "加載-存儲"架構
- 廠商: ARM公司只設計IP核(架構藍圖), 授權給其他公司(蘋果, 高通, 三星, 華為等), 由這些公司自行生產
- 其他架構
- MIPS: 經典的RISC設計, 曾在路由器, 嵌入式廣泛應用
- RISC-V: 開源的精簡指令集架構, 非常簡單化和簡潔, 發展迅猛
- AVR/PIC: 主要用于微控制器(MCU), 是 Arduino 等開發板的核心
主要分支: 語法和工具
確定了架構主干后, 你會遇到具體的 “方言” 和工具
除了不同風格的語法, 不同的匯編器也有會自己的宏和處理指令
- x86 分支下兩條路
- Inter 語法
- 特點: 指令 目標操作數, 源操作數, 例: mov eax, 5
- 代表匯編器
- NASM: 跨平臺, 開源, 語法清晰一致
- MASN: 微軟官方工具, 主要用于Windows環境
- AN&T 語法
- 特點: 指令 源操作數, 目標操作數, 例: mov $5, %eax
- 代表編譯器
- GAS (GNU Assembler): Linux 和 GCC 編譯器的默認后端
- Inter 語法
- ARM 分支下的路
- 語法: 語法風格相對統一, 主要是 GNU 匯編風格
- 編譯器:
- GAS: Linux 下編譯 ARM 代碼的標準工具
共同的地貌: 核心概念
無論你走在哪條主干和分支上, 有些地貌特征是共通的, 這就是匯編語言的 核心概念, 也是學習的重點
- 寄存器(Registers): CPU 內部高速存儲單元
- 內存尋址模式(Memory Addressing Modes): 如何計算出操作數在內存中的地址. 如 直接尋址, 寄存器間接尋址, 基址變址尋址等.
- 指令集(Instruction Set)
- 數據傳送: MOV, PUSH, POP, LEA
- 算數運算: ADD, SUB, INC, DEC, MUL, DIV
- 邏輯運算: AND, OR, XOR, NOT
- 控制流: JMP, CALL, RET, 以及各種條件跳轉
- 程序結構(Program Structure): 如何劃分代碼段, 數據段; 如何使用標簽(Labels)
- 系統調用與中斷(Syscalls & Interrupts): 如何讓操作系統內核為你服務(例: 輸出文字, 讀取文件)
延伸: 跨平臺 & 跨架構
- 架構(Architecture): 底層硬件藍圖, 指的是CPU的設計, 它定義了:
- 指令集: CPU 能夠理解和執行的基本命令集合(例: ADD, MOV 等), 不同架構之間最根本的區別
- 寄存器
- 內存訪問方式
- 平臺(Platform): 完整的運行環境, 指的是硬件架構和操作系統的組合, 它提供了軟件運行的完整生態系統
- Windows on x86-64: 最常見的PC平臺
- Linux on x86-64: 筆記本電腦, 服務器
- Linux on ARM: 智能手機, 平板, 嵌入式等
- MaxOS on x86-64: 2019年之前的蘋果Mac電腦
- MaxOS on ARM: 搭載M系列芯片的蘋果Mac電腦
跨平臺
同一份源代碼編譯出來的程序, 或者同一個解釋型程序, 能夠在不同的操作系統上運行, 不需要修改代碼
關心的是: 操作系統的差異, 例: 文件路徑(c:\ vs /), 動態庫格式(.dll vs .so), GUI框架等
如何實現:
- 用戶需要先安裝一個 運行時環境 或 虛擬機 (如 JVM, Python解釋器), 這個運行時環境本身是需要為特定平臺專門編譯的
- 你的源代碼被編譯成一種中間格式(如java的.class字節碼). 這個中間格式是跨平臺, 跨架構的. 當用戶在具體平臺運行它時, 本地的運行環境會負責將中間格式 “翻譯” 成當前平臺能理解的本地指令
跨架構
同一份源代碼編譯出來的程序, 能夠在不同的CPU架構上運行
關心的是: CPU指令集的差異, 軟件必須被編譯成目標架構能理解的機器碼
如何實現:
-
方案一: 分發代碼
- 提供程序的源代碼, 用戶在自己的機器上針對自己的架構自行編譯
- 例: Linux 開源軟件
-
方案二: 提供多個二進制版本
- 開發者提前為不同的架構分別編譯好, 用戶根據自己的CPU下載對應的版本
- 例: Python 官網同時提供 x86-64 和 ARM64 的安裝包
總結
以 GAS vs. NASM 為例
特性 | GAS (GNU Assembler) | NASM (Netwide Assembler) |
---|---|---|
跨架構 | 是。一個工具,多種架構 | 否。只專注于x86/x86-64架構 |
跨平臺 | 是。可在Win, Linux, macOS等系統上運行 | 是。可在Win, Linux, macOS等系統上運行 |
默認語法 | AT&T 語法 | Intel 語法 |
“家族” | 屬于龐大的GNU工具鏈(GCC, ld, objdump等) | 是一個獨立的、專注的匯編器 |
NASM 不支持跨架構 ≠ 無法在ARM架構上的系統安裝
讓我們分兩層理解:
- NASM 本身是一個程序, 可以被編譯為特定操作系統和架構上運行的版本. 這也是跨平臺的特性
- NASM 的功能, 無論NASM在哪個操作系統上運行, 它的核心功能只有一個: 將 Inter 語法格式的 x86/x86-64 匯編源代碼 匯編成 x86/x86-64 架構的機器碼
因此, 會產生以下情況:- 在 x86 Linux 上: 可以運行 NASM, 它正常工作, 生成 x86 的 .o 目標文件
- 在 ARM Linux 上: 你也可以安裝和運行一個專門為 ARM 架構編譯的 NASM 程序, 但是, 這個 NASM 程序仍然智能處理 x86匯編代碼, 并試圖輸出 x86 機器碼.
- 這在大多數情況下是沒有意義的, 生成的x86機器碼在 ARM CPU上無法直接執行
- 這種操作通常只用于 交叉編譯的特殊場景, 比如你在一個 ARM 服務器上為 x86 電腦編譯程序