開始讀Linux內核相關書籍時,在書店裏碰到一個計算機專業科班出身的朋友,向他請教時,他認爲學習Linux內核不須要彙編和計算機體系結構等相關的知識。但是結合到如今的學習經歷,我卻愈來愈以爲爲了搞清楚Linux內核相關設計和運行原理,本身那點自學來的彙編知識不但不夠,還大大的須要補充。本文是我今日對微處理器寄存器學習總結所得,主要是翻譯自《Intel 微處理器英文第7版》,閱讀的過程當中我參考了網上能夠下載到的該書第六版的中文版和一篇關於寄存器在Visual Stdio 編譯器中慣用方法的文章《彙編-32位寄存器的功能及其使用之整理篇》一文,可是考慮以後沒有將其大段引用。html
編程模型編程
按位分類函數
8086的編程模型包括8、16和32位的寄存器。性能
八位的寄存器包括AH,AL,BH,BL,CH,CL,DH和DL。學習
16位寄存器包括AX,BX,CX,DX,SP,BP,DI,SI,IP,FLAGS,CS,DS,ES,SS,FS,和GS。測試
擴展的32位的指令包括EAX,EBX,ECX,EDX,ESP,EBP,EDI,ESI,EIP和EFLAGS。編碼
全部的32位寄存器和16位寄存器中的FS或者GS都僅僅可以在80386以上使用。spa
按照用途分類操作系統
一些寄存器是通用寄存器或者多用途寄存器,而另外的一些則是特殊用途的寄存器。多用途寄存器包括EAX,EBX,ECX,EDX,EBP,EDI和ESI。這些寄存器都是可變大小的,而且可以被應用程序用於幾乎全部的目的。.net
也有人按照用途將這些寄存器分爲如下四類:
4個數據寄存器(EAX、EBX、ECX和EDX)
2個變址和指針寄存器(ESI和EDI) 2個指針寄存器(ESP和EBP)
6個段寄存器(ES、CS、SS、DS、FS和GS)
1個指令指針寄存器(EIP) 1個標誌寄存器(EFlags)
寄存器的易失性
一些寄存器在函數中經常是變化的,而另一些倒是不變的。這是編譯器所決定的。由於寄存器是不會自動保存的(雖然有些彙編語言會自動保存,可是x86 是不會的),因此編碼時要本身保存。這句話的意思是:當一個函數被調用,是不保證在函數返回時,易失寄存器上的值不變的;可是函數必須負責保存非易失寄存器中的值。
微軟編譯器的寄存器使用習慣以下:
1) 易失寄存器: ecx, edx
2) 非易失寄存器 : ebx, esi, edi, ebp
3) 其餘特殊寄存器 : eax, esp (discussed later)
多用途寄存器
EAX(累加器) EAX能夠被引用成32位(EAX),16位(AX)和8位(AH,HL)。注意若是8位或者16位寄存器被尋址,則僅僅會改變32位寄存器的一部分而不會影響到其餘部分。累加器能夠被用來作加減乘除這樣的指令也能夠被用做一些調整指令。對於這些調整指令,累加器具有一個特殊目的,可是它仍然一般被認爲是多用途寄存器。在80386之上的微處理器(注意不是全部版本)中,EAX寄存器也能夠持有內存系統地址的偏移地址。
EBX (基索引) EBX能夠被做爲EBX、BX,BH和BL被尋址,在全部版本的微處理器(包括16位)中,BX寄存器有時會持有內存系統位置的偏移地址。在80386以上,EBX也能夠用來尋址內存數據。
ECX(計數) ECX是一個通用目的計數器,它持有多種指令的計數。自80386以上,ECX計數器也能夠持有內存數據的偏移地址(注意此處不是全部版本)。那些使用了計數器的指令包括:重複字符串指令(REP/REPE/REPNE);和shift,rotate,和LOOP/LOOPD指令。Shift指令和rotate指令使用CL做爲計數器。重複字符串指令使用CX,而LOOP/LOOPD指令使用CX或者ECX指令。
EDX(數據) EDX是一個通用目的寄存器它持有乘法運算結果的一部分或者除法運算以前被除數。自80386以上該寄存器也被用做尋址內存數據。
EBP(基指針) 在全部版本的微處理器中,EBP指向內存位置,而且用做內存數據傳輸。該寄存器能夠被做爲BP或者EBP尋址。
EDI(目標索引) EDI一般尋址一些字符串指令的字符串目標數據。它也能夠起到32或者16位通用寄存器的做用。
ESI(源索引) ESI被用做ESI或者SI,源索引寄存器一般尋址字符串指令的源字符串數據。像EDI同樣,ESI也能夠起到通用寄存器的做用。
特殊目的寄存器
特殊目的寄存器包括EIP,ESP和EFLAGS;和段寄存器CS,DS,ES,SS,GS。
EIP(指令指針) EIP尋址做爲代碼段定義的內存段中的下一個指令。該寄存器是實模式下的IP指令和80386以上的保護模式中的EIP指令。注意8086,8088,和80286不包含EIP寄存器,僅僅80286以上的寄存器有保護模式。指令指針指向程序的下一條指令,被微處理器用來尋找代碼段中下一個序列指令。指令指針能夠被經過jump或者call指令修改。
ESP(堆棧指針) ESP尋址被稱爲堆棧的內存區域。堆棧內存以指針的形式存儲數據而且在下文尋址堆棧數據的指令裏獲得解釋。該寄存器用在16位是SP,用在32位是ESP。
EFLAGS EFLAGS指示微處理器的條件而且控制它的操做。下圖顯示了微處理器全部版本的註冊器標誌。注意這些標誌都是後向兼容的。8086-80286擁有一個FLAG寄存器80386以上包括一個EFLAG寄存器(將標誌擴展到32位)。
最右邊的信號的五個位和溢出標誌會在多個算數和邏輯指令執行以後會被改變。這些全部的標誌對於數據傳遞和程序控制都是不被改變的。一些標誌也被用來在微處理器中控制特徵。最右邊的五個信號會被大多數的算數運算和邏輯運算改變,但仍然不會被數據傳遞和邏輯操做改變。
C(進位) 進位標誌保存加法之後的進位或減法之後的借位,也能夠用進位標誌
指示由某些程序或進程引起的錯誤條件,這在DOS功能調用尤爲有用。
P (奇偶性) 奇偶標誌表示結果數中1的個數是奇數仍是偶數,是奇數則該標誌
是邏輯0,是偶數則該標誌是邏輯to若是某個二進制數含有3個
爲I的位,它的奇偶性爲奇數。若是某個二進制數包含O個爲l的
位、它的奇偶性爲偶數。奇偶性標誌在現代程序設計中不多使用,
它是早期I}tet微處理器在數據通訊環境中校驗數據的一種手段。今
天,奇偶校驗經常由數據通訊設備完成,而不是由微處理器完成。
A(輔助進位)輔助進位標誌保存加法後的結果中第3位與第4位之間的進位(半
進位),或者減法後的結果中第3位與第4位之間的借位。D DA和
BAS指令測試這個特殊標誌位,以便在BCD加法或減法後對AL
中的值進行十進制調整。除此之外,微處理器或者任何其餘指令都
不使用A標誌位。
Z (零) 零標誌表示一個算術或邏輯操做的結果是否爲0。若是Z=1,表示
結果爲0若是Z=0,表示結果不爲0。
S (符號) 符號標誌存放算術或邏輯運算指令執行後結果的算術符號。若是S=1, 則符號位(數的最左一位)爲1或爲負;若是S=0,則符號位爲0或爲正。
T (捕捉) 陷阱標誌可以激活微處理器芯片上的調試功能(對程序進行調試,
以便找到錯誤或故障)。若是T標誌爲容許(爲1),則微處理器根
據調試寄存器和控制寄存器的指示中斷程序流。若是T標誌爲0,
則禁止捕捉(調試)性能。VC 程序能夠利用陷阱特性和調試寄存器調 試有缺陷的軟件。
I (中斷) 中斷標誌控制INT(中斷請求)輸人開關的操做。若是I=1,則INTR開 關被容許,若是ICU,則INTR引腳被禁止。I標誌的狀態由SLI(置位 I標誌)和CLI(清除I標誌)指令控制。
D (方向) 在串指令操做期間,方向標誌爲DI和SI寄存器選擇遞增方式或遞
減方式。若是D=1.則寄存器內容自動地遞減;若是D=0,則寄存器內容 自動地遞增。D標誌用STD (置位方向)指令置位,用CLD(清除方向) 指令清除。
O (溢出) 溢出標誌在有符號數進行加或減時可能出現。溢出指示運算結果已
超出機器可以表示的範圍。對於無符號的操做,不考慮溢出標誌。
IOPL(I/O優先級)輸人/輸出優先級標誌用於保護模式操做時爲刀。設備選擇優先級。
若是當前任務的優先級高於工IOPL,則到O指令能順利執行若是
IOPL比當前任務的優先級低。則產生中斷,致使執行程序被掛起。
注意,00級是最高優先級,11級是最低優先級。
NT(任務嵌套) 任務嵌套標誌指示在保護模式下當前執行的任務嵌套於另外一任務
中。當任務被軟件嵌套時,這個標誌置位。
RF(恢復) 恢復標誌和調試寄存器一塊兒使用,控制在下條指令後恢復程序的
執行。
VM(虛擬方式)虛擬方式標誌用於在保護模式系統中選擇虛擬操做模式。虛擬模式
系統容許多個1 MH長的DOS存儲器分區共存於存儲器系統中。這
樣能夠容許系統執行多個DOS程序。
AC(對齊檢查)當尋址一個字或雙字時,若是地址不是在字或雙字的邊界上,對齊
檢查標誌被激活爲1。只有8048bSX微處理器包含對齊檢查位,這
個位用來與其配套的協處理器80487SX同步。
VIF(虛擬中斷) 虛擬中斷標誌是中斷標誌位的副本,只有Pentium-.Fentiurn 4微處
理器纔有。
VIP(虛擬中斷掛起)虛擬中斷掛起標誌爲Fentium~Pentium 4微處理器提供有關虛擬模
式中斷的信息。它用於多任務環境下,爲操做系統提供虛擬中斷和
中斷掛起信息。
ID(標識) 標識標誌指示Pentium-Pentium 4微處理器支持CPUID指令。CPUID
指令給系統提供有關Pentium微處理器的信息,如版本號和製造商.
段寄存器
其他的寄存器,段寄存器與其餘寄存器一塊兒合併生成內存地址。在衆多微處理器中有的有四個段寄存器,有的有六個段寄存器。段寄存器在實模式和保護模式的功能不一。
CS(代碼) 代碼段是保存微處理器執行代碼的內存段。代碼段寄存器持有段的起始位置。在實模式它定義64K內存段的起始位置。在保護模式它選擇它選擇一個描述符來描述段得起始位置和長度。在8088-80286上代碼段的限制是64K,在80386以上的保護模式中它的大小是4G。
DS(數據) 數據段是一個內存段包括大多數的程序中使用的數據。數據段中的數據被經過偏移地址或者持有偏移地址的其餘寄存器的內容訪問。像代碼段同樣,它的大小在8088-80286上代碼段的限制是64K,在80386以上的保護模式中是4G。
ES(附加) 附加段是一個用來保存一些字符串指令的目標數據的附加數據段。
SS(堆棧) 堆棧段定義了堆棧使用的內存區域。堆棧的入口地址由堆棧段和堆棧指針寄存器決定,BP寄存器也能夠在堆棧寄存器裏尋址。
FS和GS 這兩個段是80386-Pentium4 微處理器中提供的段來程序獲得兩個附加段。Windows 用它完成一些內部操做,對它們沒有明確的定義。
參考內容
《Intel 微處理器英文第7版》
《彙編-32位寄存器的功能及其使用之整理篇》http://hi.baidu.com/shongbee2/blog/item/e3da9d38e053f72f97ddd888.html