這里介紹8個通用寄存器和兩個特殊的寄存器
其余寄存器https://blog.csdn.net/weixin_4427
8個通用寄存器
對於8個通用寄存器來說, 一個寄存器是一個4字節大小的物理單元,也就是數據寬度為DWORD,為了方便實現byte和word數據寬度的操作。又將這個寄存器再次進行划分。以EAX單元為例子。EAX是一個4字節的32位寄存器,為了方便對WORD數據寬度進行處理,將EAX低位的兩個字節命名位AX寄存器,同樣的。為了方便byte的操作。將AX的寄存器的高8位和低8位分別位AH和AL寄存器。如圖:
根據這樣的方式,8個寄存器再次被划分位多個子單元,得到了16和8位的寄存器。
16位 | 8位 | |
---|---|---|
EAX: | AX | AH、AL |
EBX | BX | BH、BL |
ECX | CX | CH、CL |
EDX | DX | DH、DL |
ESI:使用MOVS指令復制數據時,ESI儲存源數據的地址 | SI | |
EDI:使用MOVS指令復制數據時,EDI儲存復制的目的地址 | DI | |
ESP:儲存程序棧頂的內存地址 | SP | |
EBP:儲存程序棧底的內存地址 | BP |
如上表,只存在8個通用寄存器,然后被分成16位寄存器和8位寄存器,16位和8寄存器並沒有專門分配硬件,而是與32位寄存器通用來實現。在32位CPU中,32位寄存器EAX、EBX、ECX和EDX可以用作傳送數據、暫存數據,保存算術邏輯運算結果,同時也可以保存內存地址,即作為指針寄存器。
ESI, EDI有默認的用途,主要用於復制,兩個寄存器中都存儲內存中的地址,當使用MOVS指令進行復制時候,默認是將ESI內存地址處的數據復制到EDI保存的內存地址處,每次復制之后,ESI和EDI中保存的地址會對應的進行偏移,這樣可以連續的復制內存中一串內存地址的數據。
ESP和EBP寄存器中記錄的是當前程序的堆棧空間的地址。堆棧式計算機分配給程序的一段連續的內存塊,例如分配給程序內存編號為1000 - 5000這段內存塊,這個空間成為程序的堆棧,程序中的需要保存的數據暫存在這個空間中,並在ESP寄存器中記錄內棧頂的地址(內存小編號),EBP中保存棧低的地址。
兩個特殊的寄存器
EFL寄存器:該寄存器中的每一位用於表示一組的狀態標志,用於提供程序的狀態及進行相應的控制。該寄存器不能用於存儲其他值。其標志位含義如下:
-
-
PF [Parity flag] 如果結果的最低有效字節(least-significant byte)包含偶數個1位則該位置1,否則清零
-
AF [Adjust flag] 如果算術操作在結果的第3位發生進位或借位則將該標志置1,否則清零。這個標志在BCD(binary-code decimal)算術運算中被使用。
-
ZF [Zero flag] 若結果為0則將其置1,反之清零。
-
SF [Sign flag] 該標志被設置為有符號整型的最高有效位。(0指示結果為正,反之則為負)
-
OF [Overflow flag] 由於有符號數最高位為符號位,則第二高位置發生了進位或者借位即可判斷該數溢出。如果運算后第二高位發生了借位或者進位,該標志位置為1,反之清零。這個標志用於標志帶符號整型運算指示溢出狀態。
-
DF [Direction flag]:控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)每次執行后會自動將內存地址進行遞增或遞減。設置DF標志為1,控制串指令每次操作的內存地址會自動遞減(從高地址向低地址方向處理字符串),設置為0則使得串指令每次操作的地址為自動遞增。STD以及CLD指令分別用於設置以及清除DF標志。
-
TF [Trap flag]:將該位設置為1以允許單步調試模式,清零則禁用該模式。
-
IF[Interrupt enable flag]:該標志用於控制處理器對可屏蔽中斷請求(maskable interrupt requests)的響應。置1以響應可屏蔽中斷,反之則禁止可屏蔽中斷。
-
內存
計算機中最小的儲存單位為字節,內存也不例外,每個字節作為一個儲存單元。這樣就將內存划分成了上億個內存單元,為了方便管理這些單元,計算機選擇了對每一個內存單元進行編號,想要使用一個內存單元時,只需要指定該內存單元編號(即內存地址)即可。為了能編號盡量多的地址,計算機使用了一個4字節的數來編址內存,這樣可以對2^32塊內存進行編址,每個塊為1byte,2^32 byte = 4Gb,可以編址的內存大小為4G大小。
堆棧
堆棧提升
我們知道,在高級語言中,當我們執行一個函數調用,將會開辟一個新的棧空間,此時就需要進行堆棧提升,此時需要更改ESP和EBP寄存器中記錄的棧底和棧底指針,這樣函數中產生的值將不會影響原棧空間(黃色部分)的數據。右圖為堆棧提升后的結果,此時push數據會從1005開始添加,pop也只能到1005這個地址的數據,無法再向下pop,這樣將無法影響元堆棧的內容。
堆棧平衡
堆棧平衡實際上就是恢復堆棧內容,例如執行一次函數操作時,進行堆棧提升,開辟新的空間來供函數使用,當函數執行結束后,應該讓棧底和棧頂指針恢復到原來的位置。
簡述過程為
1.將ESP寄存器中的值,更改為EBP的值,這樣棧頂到了目前棧底的位置。ESP=1005
2.將EBP寄存器指向的內存地址中的值取出,即1000,將EBP寄存器的值改為該值1000。這樣EBP回到了1000的位置。
數據寬度
匯編語言中有三種數據寬度,分別為
-
BYTE:一個字節寬度,占8位
-
WORD:字,兩個字節寬度,占16位
-
DOUBLEWORD:雙字,四個字節寬度,占32位。
大小端模式
內存是從小到大進行編址的,儲存一個多字節的數據時候,如果內存的小地址存儲多字節數據的高位,就是大端模式。也就是說,先取數據的高位進行儲存,再依次取低位儲存。例如一個字符串"abcd",a為數據的高位,d為低位,內存會取出四個連續的內存空間來儲存這個字符串。如果這段連續內存的小地址上儲存的時a然后依次為bcd,就是大端模式。如果小地址處儲存的是低位數據,則為小端模式。
數據儲存為大端或者小端模式是由編譯器決定的。