2. CPU

CPU總是周而複始地做同一件事:從內存取指令,然後解釋執行它,然後再取下一條指令,再解釋執行。CPU最核心的功能單元包括:

上圖中畫了32條地址綫和32條數據綫,CPU寄存器也是32位,可以說這種體繫結構是32位的,比如x86就是這樣的體繫結構,目前主流的處理器是32位或64位的。地址綫、數據綫和CPU寄存器的位數通常是一致的,從上圖可以看出數據綫和CPU寄存器的位數應該一致,另外有些寄存器(比如程序計數器)需要保存一個內存地址,因而地址綫和CPU寄存器的位數也應該一致。處理器的位數也稱為字長,字(Word)這個概念用得比較混亂,在有些上下文中指16位,在有些上下文中指32位(這種情況下16位被稱為半字Half Word),在有些上下文中指處理器的字長,如果處理器是32位那麼一個字就是32位,如果處理器是64位那麼一個字就是64位。32位計算機有32條地址綫,地址空間(Address Space)從0x00000000到0xffffffff,共4GB,而64位計算機有更大的地址空間。

最後還要說明一點,本節所說的地址綫、數據綫是指CPU的內匯流排,是直接和CPU的執行單元相連的,內匯流排經過MMU和匯流排介面的轉換之後引出到晶片引腳才是外匯流排,外地址綫和外數據綫的位數都有可能和內匯流排不同,例如32位處理器的外地址匯流排可定址的空間可以大於4GB,到第 4 節 “MMU”再詳細解釋。

我們結合表 1.1 “一個語句的三種表示”看一下CPU取指執行的過程。

圖 17.3. CPU的取指執行過程

CPU的取指執行過程

  1. eip寄存器指向地址0x80483a2,CPU從這裡開始取一條5個位元組的指令,然後eip寄存器指向下一條指令的起始地址0x80483a7。

  2. CPU對這5個位元組譯碼,得知這條指令要求從地址0x804a01c開始取4個位元組保存到eax寄存器。

  3. 執行指令,讀內存,取上來的數是3,保存到eax寄存器。注意,地址0x804a01c~0x804a01f裡存儲的四個位元組不能按地址從低到高的順序看成0x03000000,而要按地址從高到低的順序看成0x00000003。也就是說,對於多位元組的整數類型,低地址保存的是整數的低位,這稱為小端(Little Endian)位元組序(Byte Order)。x86平台是小端位元組序的,而另外一些平台規定低地址保存整數的高位,稱為大端(Big Endian)位元組序。

  4. CPU從eip寄存器指向的地址取一條3個位元組的指令,然後eip寄存器指向下一條指令的起始地址0x80483aa。

  5. CPU對這3個位元組譯碼,得知這條指令要求把eax寄存器的值加1,結果仍保存到eax寄存器。

  6. 執行指令,現在eax寄存器中的數是4。

  7. CPU從eip寄存器指向的地址取一條5個位元組的指令,然後eip寄存器指向下一條指令的起始地址0x80483af。

  8. CPU對這5個位元組譯碼,得知這條指令要求把eax寄存器的值保存到從地址0x804a018開始的4個位元組。

  9. 執行指令,把4這個值保存到從地址0x804a018開始的4個位元組(按小端位元組序保存)。