学习笔记
《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
本篇内容
- 一、如何访问页目录自己的表项
- 二、如何访问页表自己的页表项
- 三、页映射位串与物理内存的对应关系
一、如何访问页目录自己的表项
页目录的线性地址是 0x FFFF F000
二、如何访问页表自己的页表项
页表的线性首地址是 0x FFC0 0000
- 代码段位于过程alloc_inst_a_page
- 完整的过程alloc_inst_a_page的作用是:分配一个页,并安装在当前活动的层级分页结构中(输入:
EBX=页的线性地址
)
; EBX寄存器 此时 存着 页的线性地址
;开始访问该线性地址所对应的页表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到该页表的线性地址
;得到该线性地址在页表内的对应条目(页表项)
and ebx,0x003ff000
shr ebx,10 ;相当于右移12位,再乘以4
or esi,ebx ;页表项的线性地址
call allocate_a_4k_page ;分配一个页,这才是要安装的页
or eax,0x00000007
mov [esi],eax
代码段的作用
- 固定地让高10位成为
0x3ff
,从而让页目录表当一次自己,再当一次“页表”
; - 会将 EBX 传入的页的线性地址,保留并移到中10位,从而找到真正的页表的物理地址;
- 会将 EBX 传入的页的线性地址,保留并移到低12位,作为
“页”
的偏移量,此时,页表作为“页”,相当于就找到了页表自己的页表项;
三、页映射位串与物理内存的对应关系
- 在内核公用数据段 core_data ,声明了一个标号
page_bit_map
,这连续的64字节长度(512比特),表示物理地址从0x0000 0000到0x0020 0000
之间的每个4KB页的分配情况,对应的位比特值是1,表示页面已经被分配使用;
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
源码补充
- alloc_inst_a_page 分配一个页 填写页目录表 页表
alloc_inst_a_page: ;分配一个页,并安装在当前活动的
;层级分页结构中
;输入:EBX=页的线性地址
push eax
push ebx
push esi
push ds
mov eax,mem_0_4_gb_seg_sel
mov ds,eax
;检查该线性地址所对应的页表是否存在
mov esi,ebx
and esi,0xffc00000
shr esi,20 ;得到页目录索引,并乘以4
or esi,0xfffff000 ;页目录自身的线性地址+表内偏移
test dword [esi],0x00000001 ;P位是否为“1”。检查该线性地址是
jnz .b1 ;否已经有对应的页表
;创建该线性地址所对应的页表
call allocate_a_4k_page ;分配一个页做为页表
or eax,0x00000007
mov [esi],eax ;在页目录中登记该页表
.b1:
;开始访问该线性地址所对应的页表
mov esi,ebx
shr esi,10
and esi,0x003ff000 ;或者0xfffff000,因高10位是零
or esi,0xffc00000 ;得到该页表的线性地址
;得到该线性地址在页表内的对应条目(页表项)
and ebx,0x003ff000
shr ebx,10 ;相当于右移12位,再乘以4
or esi,ebx ;页表项的线性地址
call allocate_a_4k_page ;分配一个页,这才是要安装的页
or eax,0x00000007
mov [esi],eax
pop ds
pop esi
pop ebx
pop eax
retf
- allocate_a_4k_page 分配一个4KB的页
allocate_a_4k_page: ;分配一个4KB的页
;输入:无
;输出:EAX=页的物理地址
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 ;没有可以分配的页,停机
.b2:
shl eax,12 ;乘以4096(0x1000)
pop ds
pop edx
pop ecx
pop ebx
ret
;-------------------------------------------------------------------------------