學(xué)習(xí)筆記
《x86匯編語言:從實(shí)模式到保護(hù)模式》
http://www.reibang.com/p/d481cb547e9f
詳細(xì)調(diào)用關(guān)系以及過程在整個內(nèi)核程序中的作用
內(nèi)核程序:過程[allocate_a_4K_page] 邏輯執(zhí)行圖解
過程[allocate_a_4K_page]
取自源碼文件 c16_core.asm
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
page_map_len equ $-page_bit_map
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
j1 .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
匯編指令 bts
bts [page_bit_map],eax 中 eax 的作用是什么寄狼?
-
bts bts [page_bit_map], 0
伐割,取標(biāo)號指向的位串的第0位
比特值,并送往CF
寄存器,將原比特
置為1
歼捐; -
bts bts [page_bit_map], 1
,取標(biāo)號指向的位串的第1位
比特值,并送往CF
寄存器铁孵,將原比特
置為1
; -
bts bts [page_bit_map], 2
房资,取標(biāo)號指向的位串的第2位
比特值蜕劝,并送往CF
寄存器,將原比特
置為1
轰异;
為什么后面接上 jnc .b2 岖沛?
-
jnc
是條件轉(zhuǎn)移指令,表示如果CF寄存器的值不為1(為0)則轉(zhuǎn)移搭独;
語法復(fù)習(xí)參見 http://www.reibang.com/p/f71416ec68ac
從標(biāo)號.b1 到標(biāo)號 .b2
- 目的:就是要在位串中找一個比特值為零的比特(找到的第一個)婴削,找到了,當(dāng)前的EAX就是這個比特在整個位串中的位置牙肝;找到了唉俗,就用EAX的值乘以0x1000作為可以分配的空閑的物理頁的物理地址,傳回配椭。
為什么最后的返回是 ret
實(shí)際上虫溜,如果從整個內(nèi)核程序全局來看,就可以很清楚地看見股缸,過
allocate_a_4K_page
本身位于公用例程段(sys_routine)
吼渡,而它且只會被同處于公用例程段
的過程alloc_inst_a_page
調(diào)用,很明顯這是段內(nèi)(內(nèi)部)調(diào)用乓序,因此使用的是ret
寺酪,而不是retf
坎背;值得一提的是,過程
alloc_inst_a_page
卻會被位于內(nèi)核代碼段(core_code)
的過程load_relocate_program
調(diào)用寄雀,那時候就是段間(不同段)調(diào)用得滤,對于過程alloc_inst_a_page
而言,最后的返回就是使用retf