本系列進入第 3 部分——匯編語言。雖然不如高級語言熟悉,但它是編譯器輸出的真實面貌,理解它能揭開程序運行的迷霧。
高級語言封裝了底層細節(寄存器分配、內存佈局等),帶來便利卻也造成「只知其然不知其所以然」。例如 Java 中 Integer 自動拆裝箱的緩存行為:
Integer a = 127, b = 127; // true Integer c = 128, d = 128; // false
這背後是編譯器生成的字節碼與 JVM 實現細節。對於 C/C++ 開發者,匯編就是編譯器產物的直接表現;對於 Java 開發者,理解底層執行機制同樣有助於寫出高效代碼。無論使用何種語言,指揮計算機工作都應了解其如何工作。
以簡單 C 函數 simple 為例:
int simple(int *xp, int y) {
int t = *xp + y;
*xp = t;
return t;
}
使用 gcc -S 生成匯編(未優化):
simple:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl 8(%ebp), %eax # 取 xp
movl (%eax), %eax # 取 *xp
addl 12(%ebp), %eax # *xp + y
movl %eax, -4(%ebp) # 存 t
movl 8(%ebp), %eax # 再取 xp
movl -4(%ebp), %edx # 取 t
movl %edx, (%eax) # *xp = t
movl -4(%ebp), %eax # 返回 t
leave
ret
啟用 -O1 優化後指令大幅減少,編譯器消除了臨時變量 t:
simple:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx # 取 xp
movl 12(%ebp), %eax # 取 y
addl (%edx), %eax # *xp + y → %eax
movl %eax, (%edx) # *xp = 結果
popl %ebp
ret
這直觀展示了優化如何減少指令、利用寄存器傳遞參數與返回值。
本章帶你走進匯編世界,感受其格式與邏輯。後續將深入講解寄存器、數據格式、控制流等核心指令。