[061][x86汇编语言]第16章 源码分析 过程[allocate_a_4K_page] 汇编指令bts

学习笔记

《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f

详细调用关系以及过程在整个内核程序中的作用

参见 https://www.jianshu.com/p/2dba8674e8fd

内核程序:过程[allocate_a_4K_page] 逻辑执行图解

[061][x86汇编语言]第16章 源码分析 过程[allocate_a_4K_page] 汇编指令bts_第1张图片
过程[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)则转移

语法复习参见 https://www.jianshu.com/p/f71416ec68ac

从标号.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

你可能感兴趣的:([061][x86汇编语言]第16章 源码分析 过程[allocate_a_4K_page] 汇编指令bts)