當(dāng)讀寫(xiě)段寄存器的時(shí)候,只需要給一個(gè)16位的段選擇子,,但是段寄存器的96位的屬性都是真實(shí)存在,,那剩下的80位怎么填充?這個(gè)16位的選擇子到底應(yīng)該怎么寫(xiě),?
全局描述符表GDT(Global Descriptor Table)在整個(gè)系統(tǒng)中,,全局描述符表GDT只有一張(一個(gè)處理器對(duì)應(yīng)一個(gè)GDT),,GDT可以被放在內(nèi)存的任何位置,但CPU必須知道GDT的入口,,也就是基地址放在哪里,,Intel的設(shè)計(jì)者門提供了一個(gè)寄存器GDTR用來(lái)存放GDT的入口地址,程序員將GDT設(shè)定在內(nèi)存中某個(gè)位置之后,,可以通過(guò)LGDT指令將GDT的入口地址裝入此寄存器,,從此以后,CPU就根據(jù)此寄存器中的內(nèi)容作為GDT的入口來(lái)訪問(wèn)GDT了,。GDTR中存放的是GDT在內(nèi)存中的基地址和其表長(zhǎng)界限 在WinDbg中按Ctrl+Break中斷到內(nèi)核,,輸入 0: kd> r gdtr //得到GDT表的基址gdtr=8003f0000: kd> r gdtl //得到GDT表的長(zhǎng)度gdtl=000003ff0: kd> dq 8003f000 //讀取GDT表的內(nèi)容8003f000 00000000`00000000 00cf9b00`0000ffff8003f010 00cf9300`0000ffff 00cffb00`0000ffff8003f020 00cff300`0000ffff 80008b04`200020ab8003f030 ffc093df`f0000001 0040f300`00000fff...//這里可以簡(jiǎn)寫(xiě)成dq gdtr0: kd> dq gdtr8003f000 00000000`00000000 00cf9b00`0000ffff8003f010 00cf9300`0000ffff 00cffb00`0000ffff8003f020 00cff300`0000ffff 80008b04`200020ab8003f030 ffc093df`f0000001 0040f300`00000fff8003f040 0000f200`0400ffff 00000000`000000008003f050 80008955`87000068 80008955`876800688003f060 00009302`2f40ffff 0000920b`80003fff8003f070 ff0092ff`700003ff 80009a40`0000ffff
GDT表的第一個(gè)段描述符為00000000`00000000,第二個(gè)為00cf9b00`0000ffff… 通用段描述符結(jié)構(gòu) ---段選擇子結(jié)構(gòu)
加載段描述符到段寄存器 除了MOV指令,,我們還可以使用LES、LSS,、LDS、LFS,、LGS指令修改寄存器. CS不能通過(guò)上述的指令進(jìn)行修改,,CS為代碼段,CS的改變會(huì)導(dǎo)致EIP的改變,,要改CS,,必須要保證CS與EIP一起 char buff[6];__asm{ les ecx,fword ptr ds:[buff] //高兩個(gè)字節(jié)給es,低四個(gè)字節(jié)給ecx char buffer[6] = {0, 0, 0, 0, 0x48, 0};//段選擇子0x48}//RPL<=DPL |
|
來(lái)自: 喜歡站在山上 > 《匯編語(yǔ)言及內(nèi)核》