2. 系統結構的變化
AMD64的出現,給全新的64位的x86帶來了很多結構上的變化:
1)64位整型數
在x86-64中,所有通用暫存器(GPRs)都從32位擴充到了64位,名字也發生了變化。8個通用暫存器(eax, ebx, ecx, edx, ebp, esp, esi, edi)在新的結構中被命名為rax, RBX, RCX, rdx, rbp, rsp, rsi, rdi,它們都是64位的。所有算術邏輯操作、暫存器到記憶體的數據傳輸現在都能以64位的整形類型進行操作。堆疊的壓棧和彈出操作都以8位元組的單位進行,而且指針類型也擁有了64位。
2)新增暫存器
在新的架構中,另外新增了8個通用暫存器:64位的r8, r9, r10, r11, r12, r13, r14, r15。這樣就有利與編譯器將函式參數、返回值等放在這些新增的GPR裡面進行傳遞,從而提高了程式的運行速度。同時,128位的MMX暫存器也從原來的8個增加到了16個。
3)增大的邏輯地址空間
目前在新的架構中,應用程式可以擁有的邏輯地址空間從4GB增加到了256TB(2^48),而且這一邏輯地址空間在未來可能增加到16EB(2^64)。
4)增大的物理地址空間
目前的x86-64架構,可以支持的物理記憶體擴展到了1TB(2^40),當然,在未來該數字可以擴展到4PB(2^52)。相比於經過PAE技術擴展的i386的64GB物理記憶體,新的架構帶來了不小的飛躍。
5)無縫使用SSE指令
新的架構借鑑和吸收了Intel的SSE、SSE2的核心指令,並在2005年加入了SSE3。在這一新的架構下,可以不再需要x87浮點協處理器來完成浮點運算了。
6)NX位
跟PAE技術一樣,新的x86-64架構也在頁表項中增加了NX位,來幫助CPU判斷該頁包含的內容是否是可以執行的,從而避免藉助“buffer overrun”導致的病毒攻擊。
7)去除舊的機制
在新架構的“長模式(long mode)”下,很多在IA32中被提出,但確不經常被作業系統用到的一些機制不再被支持。這些機制包括段式地址變化機制(FS和GS仍然被保留),任務轉移門(TSS)機制,以及虛擬86模式。當然,出於向下兼容的考慮,x86-64在“傳統模式”(Legacy mode)下,仍然對這些機制進行了保留。
3. 虛擬地址
雖然邏輯地址擴展到了64位,但是,現有的設計並沒有完全用到這64位的空間(2^64=16EB),因為使用到如此大的空間,勢必造成很大的系統開銷。AMD64在設計的時候就決定在x86-64的第一階段,只用這64位中的低48位來做頁式地址轉換,高16位(48-64位)將填充第47位相同的內容(這種方式類似於符號擴展)。如果邏輯地址不符合此規定,系統將產生異常。符合此規定的地址稱為canonical form,地址的範圍分為兩段:0 到 00007FFF-FFFFFFFF,以及FFFF8 000-0000 0000到FFFFFFFF-FFFFFFFF,總共為256TB。這種虛擬地址的分層結構,也為作業系統的設計帶來了一定便利:可以取地址的上半段保留做為作業系統的邏輯地址空間,而低地址部分做為裝載應用程式的空間,而canonical form不允許的地址空間則做為作業系統的標誌、以及特權級的標識等。當然,這樣的設計在未來地址進一步擴展的時候將稱為一個新的問題。
下圖展示了今天的設計以及未來可能的擴展:
採用64位地址空間的x86-86被稱為是運行在“長模式”(long mode)下,該模式可以看成是對PAE模式的一個擴充。長模式允許使用三個不同的物理頁面大小:4KB、2MB和1GB。在使用64位中的48位用來存放地址時,與PAE模式下的三級頁面映射機制不同的是,長模式下線性地址到物理地址的映射需要經過四級地址映射。在這四級地址映射機制中,原來PAE模式下僅擁有4個表項的頁目錄指針表被擴展到512個表項。同時,在最末一級加入一級新的頁面映射結構,該結構被稱為第四級頁表(Page-Map Level 4 Table,PML4),它跟PAE模式下的頁目錄及頁表(在長模式中,成為了頁目錄)一樣,擁有512個表項。如果地址進一步擴充,如把64位定址全部用上,該頁表就能夠擴充到33,554,432個表項,或者乾脆再加一層地址映射(PML5),當然,按照目前只用了48位的情況下,用到512個表項的PML4就已經夠用了。
可以想像,用到48位的x86-64虛擬地址的分配機制為:
0-11(12)位:頁內偏移;
12-20(9)位:由PML4來映射;
21-29(9)位:高一級頁目錄來映射(如果PS=1,則該頁表項指向一個2MB的頁);
30-38(9)位:再高一級的頁目錄來映射(如果PS=2,則該頁表項指向一個1GB的頁);
39-47(9)位:頁目錄指針表來映射。
x86-64的長模式下,對16位以及32位代碼進行了兼容,即使CPU上跑的是64位的作業系統,歷史遺留的16位以及32位代碼將都能夠在該作業系統上運行。由於x86-64兼容IA32的指令,所以,這些代碼在這種情況下運行,基本上沒有性能損耗。
在傳統模式(Legacy mode)下,x86-64的CPU的工作模式跟傳統的IA32沒有什麼兩樣。