網(wǎng)絡(luò)安全編程:x86匯編語言之寄存器
任何程序的執(zhí)行,歸根結(jié)底,都是存放在存儲(chǔ)器里的指令序列執(zhí)行的結(jié)果。寄存器用來存放程序運(yùn)行中的各種信息,包括操作數(shù)地址、操作數(shù)及運(yùn)算的中間結(jié)果等。下面來熟悉各種寄存器。
1. CPU工作模式
x86體系的CPU有兩種基本的工作模式,分別是實(shí)模式和保護(hù)模式。
實(shí)模式也稱為實(shí)地址模式,實(shí)現(xiàn)了Intel 8086處理器的程序設(shè)計(jì)環(huán)境。該模式被早期的Win 9x和DOS所支持。實(shí)模式下可以訪問的內(nèi)存為1MB。實(shí)模式可以直接訪問硬件,比如直接對(duì)端口進(jìn)行操作,對(duì)中斷進(jìn)行操作?,F(xiàn)在的CPU仍然支持實(shí)模式,一是為了與早期的CPU架構(gòu)保持兼容,二是因?yàn)樗械膞86架構(gòu)處理器都是從實(shí)模式引導(dǎo)起來的。
保護(hù)模式是處理器主要的工作模式,Linux和Windows NT內(nèi)核的系統(tǒng)都工作在x86的保護(hù)模式下。保護(hù)模式下,每個(gè)進(jìn)程可以訪問的內(nèi)存地址為4GB,且進(jìn)程間是隔離的。
2. 基本寄存器
寄存器是CPU內(nèi)部的高速存儲(chǔ)單元,訪問速度比內(nèi)存快得多,而價(jià)格也高很多(在單位價(jià)格內(nèi),寄存器的價(jià)格要比內(nèi)存貴,內(nèi)存要比硬盤貴)。CPU中,常用的寄存器分為4類,分別是8個(gè)通用寄存器、6個(gè)段寄存器、1個(gè)標(biāo)志寄存器和1個(gè)指令指針寄存器,如圖1所示。
圖1 x86處理器的基本寄存器
(1)通用寄存器
通用寄存器主要用于各種運(yùn)算和數(shù)據(jù)的傳送,每個(gè)寄存器都可以作為一個(gè)32位、16位或8位來使用,如圖2所示。
圖2 通用寄存器示意圖(一)
對(duì)于圖2來說,可以將一個(gè)寄存器分別當(dāng)8位、16位或32位來使用。EAX寄存器可以存儲(chǔ)32位的數(shù)據(jù)。EAX的低16位可以表示為AX,可以存儲(chǔ)16位的數(shù)據(jù)。AX寄存器又可分為AH和AL兩個(gè)8位的寄存器,AH對(duì)應(yīng)AX寄存器的高8位,AL對(duì)應(yīng)AX寄存器的低8位。
只有數(shù)據(jù)存儲(chǔ)寄存器可以按照這樣的方式進(jìn)行使用。由圖1可知,數(shù)據(jù)存儲(chǔ)寄存器有EAX、EBX、ECX和EDX 4個(gè)。
(2)通用寄存器的使用方式及特殊用途
指針變址寄存器可以按照32位或16位進(jìn)行使用,如圖3所示。
圖3 通用寄存器示意圖(二)
對(duì)于圖3來說,只可以將一個(gè)寄存器分為32位或16位進(jìn)行使用。ESI寄存器可以存儲(chǔ)32位的指針,其中低16位可以表示為SI,存儲(chǔ)16位的指針,但是無法像AX那樣能拆分成高8位和低8位。
各通用寄存器可以使用的方式如圖4所示。
圖4 各通用寄存器可以使用的方式
關(guān)于通用寄存器中有部分寄存器有特殊用途:
① EAX在乘法和除法指令中被自動(dòng)使用;
② CPU自動(dòng)使用ECX作為循環(huán)計(jì)數(shù)器;
③ ESP尋址堆棧(準(zhǔn)確地講,應(yīng)該是棧,其實(shí)“堆”是“堆”,“棧”是“棧”,就如同“刀劍”雖然合起來稱呼,其實(shí)是兩種不同的兵器)上的數(shù)據(jù),ESP寄存器一般不參與算數(shù)運(yùn)算,通常稱為棧指針寄存器;
④ ESI和EDI通常用于內(nèi)存數(shù)據(jù)的高速傳送,被稱為源指針寄存器和目的指針寄存器;
⑤ EBP由高級(jí)語言用來引用參數(shù)和局部變量,通常被稱為棧幀基址指針寄存器。
(3)指令指針寄存器
指令指針寄存器EIP是一個(gè)32位的寄存器。在16位的環(huán)境中,其名稱為IP。EIP寄存器通常保存著下一條要執(zhí)行的指令的地址。下一條指令的地址為當(dāng)前指令的地址加當(dāng)前指令的長度。
特殊(其實(shí)也算不上通常與特殊)情況是當(dāng)前指令為一條轉(zhuǎn)移指令,比如JMP、JE、LOOP等指令,會(huì)改變EIP的值,導(dǎo)致CPU執(zhí)行指令產(chǎn)生跳躍性執(zhí)行,從而構(gòu)成分支與循環(huán)的程序結(jié)構(gòu)。
EIP中的值始終在引導(dǎo)CPU的執(zhí)行。
(4)段寄存器
段寄存器被用于存放段的基地址,段是一塊預(yù)分配的內(nèi)存區(qū)域。有些段存放有程序的指令,有些則存放有程序的變量,另外還有其他的段,如堆棧段存放著函數(shù)變量和函數(shù)參數(shù)等。在16位CPU中,段寄存器只有4個(gè),分別是CS(代碼段)、DS(數(shù)據(jù)段)、SS(堆棧段)和ES(附加段)。
在32位CPU中,段寄存器從4個(gè)擴(kuò)展為6個(gè),分別是CS、DS、SS、ES、FS和GS。FS和GS段寄存器也屬于附加的段寄存器。
(5)標(biāo)志寄存器
在16位CPU中,標(biāo)志寄存器稱為FLAGS(有的書上是PSW,即程序狀態(tài)字寄存器)。在32位CPU中,標(biāo)志寄存器也隨之?dāng)U展為32位,被稱為EFLAGS。
關(guān)于標(biāo)志寄存器,16位CPU中的標(biāo)志已經(jīng)滿足于日常的程序設(shè)計(jì)所用,這里主要介紹16位CPU中的標(biāo)志。標(biāo)志寄存器如圖5所示。
圖5 16位的標(biāo)志寄存器
圖5說明,標(biāo)志寄存器中的每一個(gè)標(biāo)志位只占1位,而16位的標(biāo)志寄存器并沒有全部使用。16位的標(biāo)志寄存器分為兩部分,分別是條件標(biāo)志和控制標(biāo)志。
條件標(biāo)志寄存器說明如下。
① OF(Overflow Flag):溢出標(biāo)志位,溢出時(shí)為1,否則為0。
② SF(Sign Flag):符號(hào)標(biāo)志,運(yùn)算結(jié)果為負(fù)時(shí),為1,否則為0。
③ ZF(Zero Flag):零標(biāo)志,運(yùn)算結(jié)果為0時(shí),為1,否則為0。
④ (Auxiliary carry Flag):輔助進(jìn)位標(biāo)志,記錄運(yùn)算時(shí)第3位(半字節(jié))產(chǎn)生的進(jìn)位,有進(jìn)位時(shí)為1,否則為0。
⑤ (Parity Flag):奇偶標(biāo)志,結(jié)果操作數(shù)中1的個(gè)數(shù)為偶數(shù)時(shí),為1,否則為0。
⑥ CF(Carry Flag):進(jìn)位標(biāo)志,產(chǎn)生進(jìn)位時(shí)為1,否則為0。
控制標(biāo)志寄存器說明如下。
① DF(Direction Flag):方向標(biāo)志,在串處理指令中用于控制方向。
② IF(Interrupt Flag):中斷標(biāo)志。
③ TF(Trap Flag):陷阱標(biāo)志。
在日常的使用過程中,較為常用的標(biāo)志有CF、PF、ZF、SF、DF和OF。
16位CPU中的標(biāo)志在32位CPU中繼續(xù)使用,32位擴(kuò)展了4個(gè)新的標(biāo)志位。