學(xué)習(xí)筆記
《x86匯編語(yǔ)言:從實(shí)模式到保護(hù)模式》
http://www.itdecent.cn/p/d481cb547e9f
本篇內(nèi)容
- 一、如何訪問(wèn)頁(yè)目錄自己的表項(xiàng)
- 二、如何訪問(wèn)頁(yè)表自己的頁(yè)表項(xiàng)
- 三、頁(yè)映射位串與物理內(nèi)存的對(duì)應(yīng)關(guān)系
一、如何訪問(wèn)頁(yè)目錄自己的表項(xiàng)
頁(yè)目錄的線性地址是 0x FFFF F000

線性地址高20位全是1 即0xFFFFXXX 形式就可以把訪問(wèn)到頁(yè)目錄自己的表項(xiàng).png
二、如何訪問(wèn)頁(yè)表自己的頁(yè)表項(xiàng)
頁(yè)表的線性首地址是 0x FFC0 0000
- 代碼段位于過(guò)程alloc_inst_a_page
- 完整的過(guò)程alloc_inst_a_page的作用是:分配一個(gè)頁(yè),并安裝在當(dāng)前活動(dòng)的層級(jí)分頁(yè)結(jié)構(gòu)中(輸入:
EBX=頁(yè)的線性地址)
; EBX寄存器 此時(shí) 存著 頁(yè)的線性地址
;開(kāi)始訪問(wèn)該線性地址所對(duì)應(yīng)的頁(yè)表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到該頁(yè)表的線性地址
;得到該線性地址在頁(yè)表內(nèi)的對(duì)應(yīng)條目(頁(yè)表項(xiàng))
and ebx,0x003ff000
shr ebx,10 ;相當(dāng)于右移12位,再乘以4
or esi,ebx ;頁(yè)表項(xiàng)的線性地址
call allocate_a_4k_page ;分配一個(gè)頁(yè),這才是要安裝的頁(yè)
or eax,0x00000007
mov [esi],eax

如何訪問(wèn)頁(yè)表自己的頁(yè)表項(xiàng).png
代碼段的作用
-
固定地讓高10位成為
0x3ff,從而讓頁(yè)目錄表當(dāng)一次自己,再當(dāng)一次“頁(yè)表”; - 會(huì)將 EBX 傳入的頁(yè)的線性地址,保留并移到中10位,從而找到真正的頁(yè)表的物理地址;
- 會(huì)將 EBX 傳入的頁(yè)的線性地址,保留并移到低12位,作為
“頁(yè)”的偏移量,此時(shí),頁(yè)表作為“頁(yè)”,相當(dāng)于就找到了頁(yè)表自己的頁(yè)表項(xiàng);
三、頁(yè)映射位串與物理內(nèi)存的對(duì)應(yīng)關(guān)系
- 在內(nèi)核公用數(shù)據(jù)段 core_data ,聲明了一個(gè)標(biāo)號(hào)
page_bit_map,這連續(xù)的64字節(jié)長(zhǎng)度(512比特),表示物理地址從0x0000 0000到0x0020 0000之間的每個(gè)4KB頁(yè)的分配情況,對(duì)應(yīng)的位比特值是1,表示頁(yè)面已經(jīng)被分配使用;
page_bit_map db 0xff,0xff,0xff,0xff,0xff,0x55,0x55,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
db 0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

頁(yè)映射位串 與 物理內(nèi)存 的對(duì)應(yīng)關(guān)系.png
源碼補(bǔ)充
- alloc_inst_a_page 分配一個(gè)頁(yè) 填寫頁(yè)目錄表 頁(yè)表
alloc_inst_a_page: ;分配一個(gè)頁(yè),并安裝在當(dāng)前活動(dòng)的
;層級(jí)分頁(yè)結(jié)構(gòu)中
;輸入:EBX=頁(yè)的線性地址
push eax
push ebx
push esi
push ds
mov eax,mem_0_4_gb_seg_sel
mov ds,eax
;檢查該線性地址所對(duì)應(yīng)的頁(yè)表是否存在
mov esi,ebx
and esi,0xffc00000
shr esi,20 ;得到頁(yè)目錄索引,并乘以4
or esi,0xfffff000 ;頁(yè)目錄自身的線性地址+表內(nèi)偏移
test dword [esi],0x00000001 ;P位是否為“1”。檢查該線性地址是
jnz .b1 ;否已經(jīng)有對(duì)應(yīng)的頁(yè)表
;創(chuàng)建該線性地址所對(duì)應(yīng)的頁(yè)表
call allocate_a_4k_page ;分配一個(gè)頁(yè)做為頁(yè)表
or eax,0x00000007
mov [esi],eax ;在頁(yè)目錄中登記該頁(yè)表
.b1:
;開(kāi)始訪問(wèn)該線性地址所對(duì)應(yīng)的頁(yè)表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到該頁(yè)表的線性地址
;得到該線性地址在頁(yè)表內(nèi)的對(duì)應(yīng)條目(頁(yè)表項(xiàng))
and ebx,0x003ff000
shr ebx,10 ;相當(dāng)于右移12位,再乘以4
or esi,ebx ;頁(yè)表項(xiàng)的線性地址
call allocate_a_4k_page ;分配一個(gè)頁(yè),這才是要安裝的頁(yè)
or eax,0x00000007
mov [esi],eax
pop ds
pop esi
pop ebx
pop eax
retf
- allocate_a_4k_page 分配一個(gè)4KB的頁(yè)
allocate_a_4k_page: ;分配一個(gè)4KB的頁(yè)
;輸入:無(wú)
;輸出:EAX=頁(yè)的物理地址
push ebx
push ecx
push edx
push ds
mov eax,core_data_seg_sel
mov ds,eax
xor eax,eax
.b1:
bts [page_bit_map],eax
jnc .b2
inc eax
cmp eax,page_map_len*8
jl .b1
mov ebx,message_3
call sys_routine_seg_sel:put_string
hlt ;沒(méi)有可以分配的頁(yè),停機(jī)
.b2:
shl eax,12 ;乘以4096(0x1000)
pop ds
pop edx
pop ecx
pop ebx
ret
;-------------------------------------------------------------------------------