基礎:機器模型

機器碼 vs 原始碼

原始碼是人寫出來的程式——你能讀的文字,帶有名稱、字詞與結構:int main() { return 0; }。機器碼是同一個程式被改寫成 CPU 能直接執行的純數字——沒有字詞,只有編碼成指令的位元組,例如 0x55 0x48 0x89 0xE5 0x31 0xC0 這串。兩者是同一個程式的兩張臉:一張為人而做,一張為晶片而做。

你寫原始碼,是因為用數字思考令人難以忍受。但 CPU 無法執行文字;它的取指─執行週期只懂自己的機器碼,其中每條指令都是一組特定的位元樣式。編譯器(或組譯器)就是橋樑:它讀那份可讀的原始碼,為某一類 CPU 產出等價的機器碼。實務上這個翻譯多半是單向的——從機器碼回推可讀的原始碼(反編譯)既困難又會失真,因為名稱、註解與結構在編譯時都被丟棄了。

為何重要:這個區別支撐了系統程式設計的許多部分。它說明了為何你交付的是編譯好的可執行檔、而非文字檔,才能跑得快;為何機器碼綁定某個 CPU 家族,原始碼卻常能為許多平台重新編譯;為何除錯器需要額外的「除錯資訊」,才能把執行中的機器碼對回你的原始碼行;以及為何讀機器碼(反組譯)有時是唯一能確知 CPU 到底會做什麼的辦法——尤其在編譯器把你的原始碼最佳化過之後。

C 原始碼 return 0; 在 64 位元機器上,可能編譯成兩條機器指令,用組合語言寫作 xor eax, eax 再 ret——它們實際的機器碼位元組是 0x31 0xC0 0xC3。左邊可讀,右邊可執行。

同一條指令,三種視角:原始碼、組合語言助憶符、原始位元組。

組合語言不等於機器碼:組合語言是一層薄薄的、人可讀的文字形式(mov、add、名稱),由組譯器把它翻成實際的機器碼位元組。組合語言可讀;機器碼則是那些數字本身。

又稱
source versus machine codehuman-readable code versus native code原始碼與機器碼