彙編 - 暫存器
處理器操作主要涉及資料處理。這些資料可以儲存在記憶體中並從此處訪問。但是,從記憶體讀取資料和將資料儲存到記憶體中會降低處理器的速度,因為它涉及透過控制匯流排傳送資料請求到記憶體儲存單元並透過相同通道獲取資料的複雜過程。
為了加快處理器操作速度,處理器包含一些內部記憶體儲存位置,稱為暫存器。
暫存器儲存資料元素以進行處理,而無需訪問記憶體。處理器晶片中內建了數量有限的暫存器。
處理器暫存器
IA-32 架構中有十個 32 位和六個 16 位處理器暫存器。這些暫存器分為三類:
- 通用暫存器,
- 控制暫存器,以及
- 段暫存器。
通用暫存器進一步細分為以下組:
- 資料暫存器,
- 指標暫存器,以及
- 索引暫存器。
資料暫存器
四個 32 位資料暫存器用於算術、邏輯和其他操作。這四個 32 位暫存器可以用三種方式使用:
作為完整的 32 位資料暫存器:EAX、EBX、ECX、EDX。
32 位暫存器的下半部分可以用作四個 16 位資料暫存器:AX、BX、CX 和 DX。
上述四個 16 位暫存器的下半部分和上半部分可以用作八個 8 位資料暫存器:AH、AL、BH、BL、CH、CL、DH 和 DL。
其中一些資料暫存器在算術運算中具有特定用途。
AX 是主累加器;它用於輸入/輸出和大多數算術指令。例如,在乘法運算中,一個運算元根據運算元的大小儲存在 EAX 或 AX 或 AL 暫存器中。
BX 稱為基址暫存器,因為它可以在索引定址中使用。
CX 稱為計數暫存器,因為 ECX、CX 暫存器在迭代運算中儲存迴圈計數。
DX 稱為資料暫存器。它也用於輸入/輸出操作。它也與 AX 暫存器一起用於涉及大值的乘法和除法運算。
指標暫存器
指標暫存器是 32 位 EIP、ESP 和 EBP 暫存器以及相應的 16 位右半部分 IP、SP 和 BP。指標暫存器有三種:
指令指標 (IP) - 16 位 IP 暫存器儲存要執行的下一條指令的偏移地址。IP 與 CS 暫存器(如 CS:IP)一起給出程式碼段中當前指令的完整地址。
堆疊指標 (SP) - 16 位 SP 暫存器提供程式堆疊內的偏移值。SP 與 SS 暫存器(SS:SP)一起指的是程式堆疊內資料的當前位置或地址。
基址指標 (BP) - 16 位 BP 暫存器主要幫助引用傳遞給子程式的引數變數。SS 暫存器中的地址與 BP 中的偏移量組合以獲取引數的位置。BP 還可以與 DI 和 SI 結合用作基址暫存器進行特殊定址。
索引暫存器
32 位索引暫存器 ESI 和 EDI 以及它們的 16 位最右端部分 SI 和 DI 用於索引定址,有時也用於加法和減法。有兩組索引指標:
源索引 (SI) - 它用作字串操作的源索引。
目標索引 (DI) - 它用作字串操作的目標索引。
控制暫存器
32 位指令指標暫存器和 32 位標誌暫存器組合被認為是控制暫存器。
許多指令涉及比較和數學計算並更改標誌的狀態,一些其他條件指令測試這些狀態標誌的值以將控制流轉移到其他位置。
常見的標誌位是
溢位標誌 (OF) - 它指示帶符號算術運算後資料的高位(最左位)溢位。
方向標誌 (DF) - 它確定移動或比較字串資料的左右方向。當 DF 值為 0 時,字串操作採用從左到右的方向,當值設定為 1 時,字串操作採用從右到左的方向。
中斷標誌 (IF) - 它確定是否忽略或處理外部中斷(如鍵盤輸入等)。當值為 0 時,它停用外部中斷,當設定為 1 時,它啟用中斷。
陷阱標誌 (TF) - 它允許將處理器的操作設定為單步模式。我們使用的 DEBUG 程式設定了陷阱標誌,因此我們可以一次一步地執行指令。
符號標誌 (SF) - 它顯示算術運算結果的符號。此標誌根據算術運算後資料項的符號設定。符號由最左邊的最高位指示。正結果將 SF 的值清除為 0,負結果將其設定為 1。
零標誌 (ZF) - 它指示算術或比較運算的結果。非零結果將零標誌清除為 0,零結果將其設定為 1。
輔助進位標誌 (AF) - 它包含算術運算後從第 3 位到第 4 位的進位;用於專門的算術。當 1 位元組算術運算導致從第 3 位到第 4 位的進位時,AF 被設定。
奇偶標誌 (PF) - 它指示從算術運算獲得的結果中 1 位的總數。偶數個 1 位將奇偶標誌清除為 0,奇數個 1 位將奇偶標誌設定為 1。
進位標誌 (CF) - 它包含算術運算後高位(最左位)的進位 0 或 1。它還儲存移位或旋轉操作的最後一位的內容。
下表指示標誌位在 16 位標誌暫存器中的位置
| 標誌 | O | D | I | T | S | Z | A | P | C | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 位號 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
段暫存器
段是在程式中定義的特定區域,用於包含資料、程式碼和堆疊。主要有三個段:
程式碼段 - 它包含所有要執行的指令。16 位程式碼段暫存器或 CS 暫存器儲存程式碼段的起始地址。
資料段 - 它包含資料、常量和工作區。16 位資料段暫存器或 DS 暫存器儲存資料段的起始地址。
堆疊段 - 它包含資料和過程或子程式的返回地址。它作為“堆疊”資料結構實現。堆疊段暫存器或 SS 暫存器儲存堆疊的起始地址。
除了 DS、CS 和 SS 暫存器外,還有其他額外的段暫存器 - ES(額外段)、FS 和 GS,它們提供用於儲存資料的其他段。
在彙編程式設計中,程式需要訪問記憶體位置。段內的所有記憶體位置都相對於段的起始地址。段以 16 或十六進位制 10 的倍數的地址開始。因此,所有此類記憶體地址中最右邊的十六進位制數字為 0,通常不儲存在段暫存器中。
段暫存器儲存段的起始地址。要獲取段內資料或指令的確切位置,需要一個偏移值(或位移)。要引用段中的任何記憶體位置,處理器會將段暫存器中的段地址與該位置的偏移值組合起來。
示例
檢視以下簡單程式以瞭解在彙編程式設計中使用暫存器。此程式在螢幕上顯示 9 個星號以及一條簡單訊息:
section .text global _start ;must be declared for linker (gcc) _start: ;tell linker entry point mov edx,len ;message length mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov edx,9 ;message length mov ecx,s2 ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db 'Displaying 9 stars',0xa ;a message len equ $ - msg ;length of message s2 times 9 db '*'
編譯並執行上述程式碼後,將生成以下結果:
Displaying 9 stars *********