学习笔记
《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
详细调用关系以及过程在整个内核程序中的作用
内核程序:过程[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
,取标号指向的位串的第0位
比特值,并送往CF
寄存器,将原比特
置为1
; -
bts bts [page_bit_map], 1
,取标号指向的位串的第1位
比特值,并送往CF
寄存器,将原比特
置为1
; -
bts bts [page_bit_map], 2
,取标号指向的位串的第2位
比特值,并送往CF
寄存器,将原比特
置为1
;
为什么后面接上 jnc .b2 ?
-
jnc
是条件转移指令,表示如果CF寄存器的值不为1(为0)则转移;
从标号.b1 到标号 .b2
- 目的:就是要在位串中找一个比特值为零的比特(找到的第一个),找到了,当前的EAX就是这个比特在整个位串中的位置;找到了,就用EAX的值乘以0x1000作为可以分配的空闲的物理页的物理地址,传回。
为什么最后的返回是 ret
实际上,如果从整个内核程序全局来看,就可以很清楚地看见,过
allocate_a_4K_page
本身位于公用例程段(sys_routine)
,而它且只会被同处于公用例程段
的过程alloc_inst_a_page
调用,很明显这是段内(内部)调用,因此使用的是ret
,而不是retf
;值得一提的是,过程
alloc_inst_a_page
却会被位于内核代码段(core_code)
的过程load_relocate_program
调用,那时候就是段间(不同段)调用,对于过程alloc_inst_a_page
而言,最后的返回就是使用retf