CPU 與記憶體
組成電腦的成員,大概可以分為 CPU 與記憶體。記憶體就是保存資料的裝置,而 CPU 則是讀寫那些記憶體的資料並一邊運算著什麼的裝置。概念上來說,CPU 把記憶體視為可隨處讀寫的一個巨大的、由位元組(byte)構成的陣列(array)。當 CPU 想要存取記憶體的時候,必須指定他想存取第幾個位元組的記憶體位置,這個「第幾個」的數值就是「記憶體位址(address)」。舉例來說,「從位置16開始讀取8個位元組」,用陣列的方式來看的話就是,「讀取記憶體第16個位元組開始讀8個位元組分的資料」的意思。同樣的意思也可以表達成「從16號開始讀8個位元組的資料」。(譯註:這邊「16號」是地址的門牌號碼的意思,原文是寫「16番地」,是日本地址的單位。讀者可以把記憶體位址想成就像是找尋地址的感覺。)
CPU 執行的程式與其所用到的資料,都放在記憶體裡。CPU 會將「現在執行中的指令的記憶體位址」記在 CPU 裡,再從該位址把指令讀出來並執行,然後再讀出下一行、再執行。執行中指令被稱為「程式計數器」(Program Counter,PC)或「指令位址指標」(Instruction Pointer,IP)。CPU 所執行的程式的格式則被稱為「機械語言」。
程式計數器不一定都是一直線往下找接下來的指令的。CPU 可以使用叫做「分支指令」的指令,讓程式計數器跳到下一個指令以外的任意指令。if 或是迴圈等程式語言的語法就是這樣時做出來的。設定程式計數器到下一個指令以外的操作被稱為「跳躍」(jump)或是「分支」(branch)。
CPU 除了程式計數器之外,還持有少數保存資料的空間。例如 Intel 或 AMD 的處理器,就有16個可以保存64位元長的整數資料的空間。這些空間被稱之為「暫存器」(register)。從 CPU 的角度來看,記憶體是外部裝置,存取起來稍嫌費時;暫存器則是在 CPU 內部,存取起來沒有延遲時間。
許多的 CPU 指令都是使用兩個暫存器保存的數值來進行某些運算,再把運算的結果寫回(譯註:其中一個)暫存器的格式。所以在執行程式的時候,CPU 會從記憶體將資料讀取到暫存器中,在暫存器之間進行運算之後,再把運算的結果寫回記憶體。
某個特定的機械語言的集合被叫做「指令集」(instruction set)。指令集不只一種,不同CPU可以自由設計。但是因為不能執行不相容機械語言的程式,所以指令集的種類並不多。PC 上,Intel 或是相容晶片設計廠商的 AMD 使用的指令集被稱為 x86-64。雖然 x86-64 是很主流的指令集,但也不是獨佔市場。像 iPhone 或 Android 就是使用叫做 ARM 的指令集。

小知識:x86-64 指令集的由來

x86-64 指令集又被稱作 AMD64、Intel 64 或 x64。之所以這一個指令集有這麼多名字,背後是有其歷史背景因素在的。
x86 指令集在1978年由 Intel 所制定,但是將其擴充為64位元的卻是 AMD。在2000年左右,64位元處理器處理器的需求與日俱增,當時 Intel 傾全公司之力推動 Itanium 這個全新的指令集,所以刻意不去採用可能會與之競爭的64位元版本 x86 指令集。AMD 則是抓住了這個機會制定並公開了64位元版的 x86 規格,那就是 x86-64 指令集。之後由於 AMD 的品牌行銷策略,把 x86-64 改名為 AMD64。
之後,Itanium 在市場上確定失敗之後,Intel 也只剩下製作64位元版 x86 的這一選項了。在當時 AMD 已經推出了一定數量的 x86-64 的晶片了,事到如今想要制定不一樣的指令集也很困難,Intel 只好採用與 AMD 相容的指令集。也有傳聞微軟在當時也為了保持相容性,施加了一些壓力。當時的 Intel 採用和 AMD64 幾乎一樣的指令集,命名為 IA-32e。之所以不是叫64而是 IA-32e(Intel Architecture 32 extensions)也可以看出 Intel 還是把 Itanium 放在64位元戰略的中心,不願意面對指令集失敗的事實。在Intel 完全放棄 Itanium 之後,便把 IA-32e 改成 Intel 64 這個比較正常的名字了。而微軟嫌 x86-64 太長,改以 x64 稱呼 x86-64 指令集。
上述種種理由,便是 x86-64 會有這麼多名字的原因。
在開源的世界裡,大家比較偏好沒有放進任一家公司名字的 x86-64 這個稱呼,本書也一律使用 x86-64 這個名字。
Copy link