0x01原因
分段的產生原屬於安全問題。
一個程序可以自由的訪問不屬於它的內存位置,甚至可以對那些內容進行修改。這也導致安全問題 促使一種內存隔離的手段 分段的產生。
0x02分段原理
處理器要求在加載程序時,先定義該程序所擁有的段,然后允許使用這些段。定義段時需要基地址,段界限,特權級別,類型等。
在一個程序訪問cs,ss,ds,es 這些段時。處理器將會實施檢查,防止內存違規訪問。
因此有了段描述符來描述這些段的內容和權限
0x03段描述符
認識段描述符先定義全局描述符表GDT,為了跟蹤GDT 處理器有一個48位寄存器,也就是gdtr,分別是32位線性地址和16位邊界地址
訪問地址范圍就是0x00000000到0xffffffff 4gb 的映射范圍 界限地址 ffff 就是64kb 一個GDT大小是8個字節 所以GDT最最多可以定義8192個描述符
下面就是段描述符格式


看到當前的gdtr 寄存器值 和當前 ds cs es值
ds 是23解析規則就是
2 3
0010 0011
00100=4
rpl 請求特權級 3就ring3 權限
tl 0=gdtr 寄存器里面 1=ldtr里面
ds=23 指的就是GDT表的第5位置 下標在4
可以看到前5個除了第一個用於指向null的gdt 表 其他的4個把所有類型都包括了 這是因為 微軟沒用分段來隔離內存 因為gdt 大小只能8192個太少了 。
讀取少字節時性能不高,后面改用分頁來隔離內存了,又猶豫cpu只認段描述符這種格式,所以就做了4個把所有類型都包括的描述符 來解決這個問題。
但是fs gs 用的還是分段
這里fs=3b
111011= 7
f892a000~00001fff
看內存拆分就是
01 00 00 a0 92 93 c0 f8
00 0a 92 f8-01
g位為1 所以 段界限要*4kb=4096
00 00 01*4kb+0xfff 就是最后的段界限
最后就是
f892a000~1fff