一、5用户程序调用内核代码

内核统一管理描述符表,当用户程序需要获取段描述符时,就需要内核实现用户编程接口(API)

本书设计的具体实现方法是,用户程序在头部段列出所需的API的名称并258字节对齐(符号地址检索表),内核也有一个符合地址检索表,加载用户程序时拿用户程序中的符号地址检索表项搜索内核给出的表,用表内地址修改头部信息,将对应的过程地址覆盖掉原来的API名称

;用户程序内的符号地址检索表
salt_items       dd (header_end-salt)/256 ;#0x24

salt: ;#0x28
PrintString      db  '@PrintString'
				times 256-($-PrintString) db 0

TerminateProgram db  '@TerminateProgram'
				times 256-($-TerminateProgram) db 0

ReadDiskData     db  '@ReadDiskData'
				times 256-($-ReadDiskData) db 0
;内核程序内的符号地址检索表
salt:
salt_1          db  '@PrintString'
                times 256-($-salt_1) db 0
                dd  put_string
                dw  sys_routine_seg_sel

salt_2          db  '@ReadDiskData'
                times 256-($-salt_2) db 0
                dd  read_hard_disk_0
                dw  sys_routine_seg_sel

salt_3          db  '@PrintDwordAsHexString'
                times 256-($-salt_3) db 0
                dd  put_hex_dword
                dw  sys_routine_seg_sel

salt_4          db  '@TerminateProgram'
                times 256-($-salt_4) db 0
                dd  return_point
                dw  core_code_seg_sel
;常量
salt_item_len   equ $-salt_4
salt_items      equ ($-salt)/salt_item_len

image-20230803090247242

指令前常加REP做循环比较

image-20230803091225054

image-20230803091320848

image-20230803091542333

比较方向

image-20230803091905539

重定位符号地址:

load_relocate_program:

        ... ; 建立完段描述符

        ;重定位SALT
        mov eax,[edi+0x04]
        mov es,eax ; es -> 用户程序头部段
        mov eax,core_data_seg_sel
        mov ds,eax ; ds -> 内核数据段

        cld ;清除标志位

        mov ecx,[es:0x24] ;用户程序的SALT条目数
        mov edi,0x28 ;用户程序内的SALT位于头部内0x28处
    .b2: ;外循环
        push ecx
        push edi

        mov ecx,salt_items
        mov esi,salt
        
    .b3: ;内循环
        push edi
        push esi
        push ecx

        mov ecx,64 ;检索表中,每条目的比较次数 
        repe cmpsd ;每次比较4字节 
        jnz .b4
        mov eax,[esi] ;若匹配,esi恰好指向内核salt其后的地址数据
        mov [es:edi-256],eax ;将用户salt的字符串改写成偏移地址 
        mov ax,[esi+4]
        mov [es:edi-252],ax ;以及段选择子 
    .b4:
        pop ecx
        pop esi
        add esi,salt_item_len ;下一个内核salt条目
        pop edi ;回到本次用户程序salt条目开头,从头比较 
        loop .b3

        pop edi
        add edi,256 ;下一个用户程序salt条目
        pop ecx
        loop .b2

        mov ax,[es:0x04] ;取出用户程序头部的选择子,用于返回

        pop es ;恢复到调用此过程前的es段 
        pop ds ;恢复到调用此过程前的ds段

        pop edi
        pop esi
        pop edx
        pop ecx
        pop ebx

        ret

用户程序调用内核过程

SECTION code vstart=0
start:
         mov eax,ds
         mov fs,eax ;ds, fs -> 用户程序头部段
     
         mov eax,[stack_seg]
         mov ss,eax
         mov esp,0
     
         mov eax,[data_seg]
         mov ds,eax
     
         mov ebx,message_1
         call far [fs:PrintString]
     
         mov eax,100 ;逻辑扇区号100
         mov ebx,buffer ;缓冲区偏移地址
         call far [fs:ReadDiskData] ;段间调用,读提前写入硬盘的文本文件内容
     
         mov ebx,message_2
         call far [fs:PrintString]
     
         mov ebx,buffer 
         call far [fs:PrintString]
     
         jmp far [fs:TerminateProgram] ;将控制权返回到系统 
      
code_end:

十六进制形式显示双字:

put_hex_dword:                              ;在当前光标处以十六进制形式显示
                                            ;一个双字并推进光标 
                                            ;输入:EDX=要转换并显示的数字
                                            ;输出:无
         pushad ;将所有双字寄存器压栈
         push ds
      
         mov ax,core_data_seg_sel           ;切换到核心数据段 
         mov ds,ax
      
         mov ebx,bin_hex                    ;指向核心数据段内的转换表:bin_hex db '0123456789ABCDEF'
         mov ecx,8
  .xlt:    
         rol edx,4
         mov eax,edx
         and eax,0x0000000f
         xlat ;查表指令
      
         push ecx
         mov cl,al                           
         call put_char
         pop ecx
       
         loop .xlt
      
         pop ds
         popad
         retf
      

image-20230803115839818

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值