如何构造栈段描述符
如何構造棧段描述符
本文要討論的是:對于x86保護模式(32位),已知棧空間的起始地址和結束地址,如何定義棧段描述符?ESP的初始為多少?
為了簡化問題,設定約束條件如下:
1. 棧段向下擴展
2. B=1
3. G=1
4. 分頁機制關閉
問題分析:數據段描述符的格式如下
如果你不懂各個字段的含義,可以參考我的博文:
數據段描述符和代碼段描述符(一)——《x86匯編語言:從實模式到保護模式》讀書筆記10
根據約束條件,G=1,B=1,AVL可以設為0,P=1,DPL根據需要來設置,TYPE=0x06(可讀可寫,向下擴展);所以問題簡化為求基地址和段限長,只要算出這兩個字段,就可以順利構造出棧段描述符。
假設我們已經有一片連續的物理內存,要把這段內存作為棧空間。設最低端的物理地址為LA,最高端的物理地址為HA,且棧空間大小為SIZE;如下圖所示:
設有效界限(Effect Limit)為EL;有效偏移(Valid Offset)為VO;
根據《Intel Architecture Software Developer’s Manual Volume 3:System Programming》第4.3節的說明(請注意黃色的字):
于是,可以知道VO的范圍:
因為基地址加上偏移值才是實際的物理地址,假設描述符中的基地址為BA,那么可以得出:
(3)式減去(2)式得到:
又根據棧空間的大小為SIZE,可得出:
把(5)代入(4)式,消去HA-LA,得到:
也就是說,知道了棧空間的大小SIZE,就能算出EL;
把(5)式代入(3)式,消去HA得到:
因為是32位的處理器,所以
把(8)式代入(7)式得:
也就是說,段描述符中的基地址BA等于棧空間的最低端地址LA加上棧空間的大小。
通過上面的推導,我們得出2個重要的公式:
但是,棧段描述符中填寫的界限值(這里用limit表示),并非是(6)式中的EL;當G=1(粒度為4KB)時,limit和EL的關系為:
當棧空間的大小是4KB的整數倍時,我們可以設
把(10)和(11)式代入(6)式,消去EL和SIZE,得
于是,我們知道描述符中的界限值該如何計算。
到這里,本文還沒有結束,我們還要推導ESP的初始值(用ESP_INIT表示)。
第一次壓棧的時候,比如
首先,ESP的值減去4,然后把EAX的值寫入偏移為[0xFFFF_FFFC,0xFFFF_FFFF]這四個單元。所以:
最后,重復我們的結論:
【end】
總結
- 上一篇: 产品经理是个实战类科目
- 下一篇: 写一函数,将两个字符串连接