X86 匯編/X86 架構
x86 架構
編輯x86 架構就如一數據加工廠, 內有各種大小的暫存器, 8 個通用暫存器(通用Register GPR), 6 個段暫存器, 1 個標誌暫存器和一個命令指針(裝了存儲區地址的暫存器和存儲器統稱指針). 64-位 x86 有更多暫存器.
16-位通用暫存器(寄存器) (通存器 GPR)名稱
編輯8個通存器:
- 累加(Accumulator) 暫存器 (AX,加存器). 用於算術運算.
- 計數(Counter) 暫存器 (CX,計存器). 用於移/環指令及循環.
- 數據(Data) 暫存器 (DX,數存器). 用於算術運算及I/O操作.
- 基(Base) 暫存器 (BX,基存器). 指向數據塊的基址(段模式中存於段暫存器 DS).
- 疊(棧)(Stack) 指針 暫存器 (SP,疊存器). 指向疊頂.
- 源號(Source Index) 暫存器 (SI,源存器). 指向流操作中的源.
- 靶號(Destination Index) 暫存器 (DI,靶存器). 指向流操作中的靶.
上述8個通存器的列舉順序與他們的入疊順序相同, 以16-位模式存取. 前綴以'E' (extended)時以32-位模式操作. 例如'EAX'是累加暫存器的32-位名. 前綴以'R'則為64-位模式, 例如'RAX'.
前4個暫存器 (AX, CX, DX 及 BX), 每個還可以高(H)低(L)字節單獨存取. 例如AX=AH || AL (||拼接符), AH表AX高字節, AL表AX低字節. 字節串表示如同數字串, 左高位右低位.
這8個通存器的存取模式可總結如下表:
暫存器 | 累加器 | 計數器 | 數據 | 基 | 疊指針 | 疊基指針 | 源 | 靶 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
64-位 | RAX | RCX | RDX | RBX | RSP | RBP | RSI | RDI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
32-位 | EAX | ECX | EDX | EBX | ESP | EBP | ESI | EDI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
16-位 | AX | CX | DX | BX | SP | BP | SI | DI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8-位 | AH | AL | CH | CL | DH | DL | BH | BL |
段存器
編輯6個段存器為:
- 疊段 (SS). 指向疊.
- 碼段 (CS). 指向代碼.
- 數段 (DS). 指向數據.
- 余段 (ES). 指向額外數據 ('E' 表 '額外').
- F段 (FS). 指向更額外數據 ('F' 後於 'E').
- G段 (GS). 指向更額外數據 ('G' 後於 'F').
現代作業系統採用內存分頁模式, 把所有段存器指向同址來禁用內存分段模式.
然而FS和GS依然用於內存分段模式, 用於線程內數據存取.
EFLAGS 標誌暫存器
編輯此32-位存標器存儲運算結果狀態和處理器狀態的雙值(0或1)標誌集.
這些標誌位為:
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ID | VIP | VIF | AC | VM | RF |
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
0 | NT | IOPL | OF | DF | IF | TF | SF | ZF | 0 | AF | 0 | PF | 1 | CF |
名字為0與1的標誌為保留位不要操作.
The different use of these flags are: | |
---|---|
0. | CF (Carry Flag) : 搬位標, 進位或借位溢出時顯1,否則顯0. |
2. | PF (Parity Flag): 偶1標. 運算結果最低字節有偶數個1位時顯1, 否則顯0. |
4. | AF (Auxiliary Carry Flag): 副搬位標. BCD碼算術運算中進借位溢出, 即運算結果第三位發生進借位時顯1, 否則顯0. |
6. | ZF (Zero Flag): 零標. 運算結果為0時顯1否則顯0. |
7. | SF (Sign Flag): 號標. 顯運算結果最高位. |
8. | TF (Trap Flag): 阱位. 置1啟用單步調試, 清0禁用. |
9. | IF (Interrupt Enable Flag): 允截標,或中斷使能標. 置1允許響應可蔽中斷, 清0時禁止. |
10. | DF (Direction Flag): 方向標. 控制串操作方向. 置1時從高址向低址行進, 清0反之. |
11. | OF (Overflow Flag): 溢出標. 有號算術運算結果溢出暫存器時顯1, 否則顯0. |
12-13. | IOPL (I/O Privilege Level field): I/O特權級域(2 位). 表示當前程序之I/O特權級. |
14. | NT (Nested Task flag): 任務鏈標. 當前任務連結了前一任務時置1, 否則清0. |
16. | RF (Resume Flag): 復標. 控制處理器對除障異常的響應. |
17. | VM (Virtual-8086 Mode Flag): 幻8086模式標. 置1入幻8086模式, 清0回保護模式. |
18. | AC (Alignment Check (or access control) Flag): 對齊檢查或存取控制標. 置1 使能用戶模式數據存取之對齊如AM位在CR0暫存器中為1. |
19. | VIF (Virtual Interrupt Flag): 幻截標. 允截標的虛像. |
20. | VIP (Virtual Interrupt Pending flag): 幻截掛標. 置1若有截掛焉. |
21. | ID (Identification Flag): 身份標. 置1支持CPUID指令. |
命令指針
編輯若無分支完成, 命令指針存有下一指令.
命令指針只能在 call
指令完後通過疊來讀取.
內存
編輯x86內存為字節編址, 即每個字節有佔用一個唯一地址, 址號小的為低址, 址號大的為高址. x86 架構數據放置為小尾式, 即多字節數據在內存中放置時, 字節權位高低對應其地址高低, 即權序與址序相同. 大尾模式中權序與址序相反.
尋址(供數)模式
編輯供數模式表示操作數的提供方式. (下文中的搬, 搬的是電子信號, 實為複製)
- 暫存器供數
- (暫存器提供操作數)
mov ax, bx ; 把 bx 中的值搬入 ax
- 立即數
- (操作數由處理器產生)
mov ax, 1 ; 把数1搬入ax
又如
mov ax, 010Ch ; 把数0x010C 搬入ax
- 直接內存供數
- (變量名實為內存地址, 變量值存儲於該址中)
.数
变量名 dw 0abcdh ; 变量名 = 0xabcd
.码
mov ax, [变量名] ; 把变量值搬入ax (ax=0xabcd)
- 直接內號(offset)供數
- (可用算術改變地址)
字节表名 db 12,15,16,22,..... ; 字节表名实为基址
mov al,[字节表名+2] ; 将16搬入al
mov al,字节表名[2] ; 同上
- 暫存器間接供數
- (暫存器內容為某內存地址, 所供之數乃此內存地址中的數)
mov ax,[di]
- 此模式可用的暫存器 BX, BP, SI, DI
64-位通用暫存器
編輯64-位 x86 加了8個通用暫存器, R8至R15, 並對32-位暫存器更名以表64位:
- R0 為 RAX.
- R1 為 RCX.
- R2 為 RDX.
- R3 為 RBX.
- R4 為 RSP.
- R5 為 RBP.
- R6 為 RSI.
- R7 為 RDI.
- R8,R9,R10,R11,R12,R13,R14,R15 無別名.
- R0D~R15D 為這些暫存器的低詞(雙字,32位). 例, R0D 為 EAX.
- R0W~R15W 為這些暫存器的低字(16位). 例, R0W 為 AX.
- R0L~R15L 為這些暫存器的低符(字節,8位). 例, R0L 為 AL.
新增了8個控制寄存器(CR8 - CR15)和8個調試寄存器(DR8 - DR15),供系統使用。
此外, 64-位 x86 CPU 還新增了 8 個128位 SSE 暫存器,達到 16 個128-位暫存器 ( XMM0~XMM15). 新的Intel 與 AMD CPU支持AVX, 在這些 CPU 中,XMM 暫存器實為256-位 暫存器 ( YMM0~YMM15)的低128位。 YMM 暫存器和 XMM 暫存器均可被AVX指令整取做並行處理.
疊(棧)
編輯疊乃後入先出(LIFO) 數據結構; 數據順序堆入疊而反序取出. 下面的程序片段描述了調用處理任務前後的暫存器保存(入疊)與恢復(出疊). 處理器乃一加工廠, 入疊出疊可看作加工現場的清場與恢復.
mov ax, 006Ah
mov bx, F79Ah
mov cx, 1124h
push ax
AX值堆入疊內, 疊內此時值為0x006A.
push bx
BX值堆入疊內, 疊內有值0x006A 和 0xF79A.
push cx
疊內有值0x006A, 0xF79A, 和 0x1124.
call 处理任务
調用處理任務.
pop cx
搬疊頂值入CX, 0x1124; 疊內剩值0x006A 和 0xF79A.
pop bx
搬疊頂值入BX, 0xF79A; 疊內剩值 0x006A.
pop ax
搬疊頂值入AX, 0x006A; 疊空.
疊用於函數和過程之參數傳遞, 也在call
調用中跟蹤流程, 還可用於臨時存儲.
CPU 運行模式
編輯實模式
編輯x86啟動或復位之後進入實模式, 自該模式可進入其他模式. 很多引導程序和BIOS程序通常運行於該模式, 此模式是Intel 8086的原生模式.
保護模式
編輯x86-32和x86-64的原生模式. 此模式的眾多功能之一是可以直接在保護的多任務環境中直接執行實模式程序. 此任務級模式稱幻8086模式, 非處理器模式.
系統管理模式
編輯此模式給作業系統或程序提供一個透明機制去實現電源管理和系統安全等平台相關的功能.
內存組織
編輯平內存模型
編輯該模型下代碼, 數據 和 棧全處於統一地址空間. 現代作業系統(如Linux, Windows)中的編程基本上是本模式. 所有32-位暫存器都可用於尋址整個空間.
分段內存模型
編輯一個程序的代碼, 數據和棧可出處於不同的內存段中, 這可由分段內存模型提供. 程序採用邏輯地址存取段中的字節. 邏輯地址又稱遠指針, 由段選擇器+偏移組成. 運行於IA-32中的程序可以用段選擇器選擇高達16283個內存段, 而每個段最長可達232字節. 從邏輯地址向線性地址的轉換由處理器完成, 對應用程式透明. 用內存分段來隔離程序, 可提高程序和系統的可靠性.
實模式下的內存模型
編輯16-位的 Intel 8086 卻用20-位地址空間. 基地址+偏移的方式用於存取此空間.
實模式中, 內存地址=基地址+偏移(通存器). 基地址=段存器x16 (或左移4位) , 此方式可存取 1 MB的空間. 因此段存器被用於內存分片, 甚至不同程序運行於不同的內存片中以實現程序的內存獨立.
由於存偏移的通存器也只有16位(Intel 8086), 因此每段最大為64KB. DOS的.COM程序即運行於此模式中. 由於.COM程序含256B的程序信息, 因此只有65280B可供用戶使用. 由此可見早期程序之小.