美文网首页
[041][x86汇编语言]第十五章 终止当前任务 子程序 te

[041][x86汇编语言]第十五章 终止当前任务 子程序 te

作者: AkuRinbu | 来源:发表于2018-06-28 05:34 被阅读8次

    学习笔记

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

    复习

    代码运行后的内存状态

    https://www.jianshu.com/p/a286eceb0a10

    任务切换过程中NT位、B位以及TSS指针域变化规则

    https://www.jianshu.com/p/44c9434b2c95

    思考:为什么需要 子程序 terminate_current_task

    子程序 terminate_current_task 处理任务切换

    • 源码(位于内核程序c15_core.asm
    terminate_current_task:                 ;终止当前任务
                                            ;注意,执行此例程时,当前任务仍在运行中
                                            ;此例程其实也是当前任务的一部分
            pushfd              
            mov edx,[esp]       ;获得EFLAGS寄存器内容
            add esp,4           ;恢复堆栈指针
            
            mov eax,core_data_seg_sel       ;内核数据段选择子 
            mov ds,eax
            
            test dx,0100_0000_0000_0000B    ;测试(EFLAGS寄存器)NT位
            jnz .b1                         ;当前任务是嵌套的,到.b1执行iretd
            mov ebx,core_msg1               ;jmp
            call sys_routine_seg_sel:put_string 
            jmp far [prgman_tss]            ;prgman_tss 程序管理器基地址和选择子
            
            
    .b1:    
            mov ebx,core_msg0               ;call
            call sys_routine_seg_sel:put_string
            iretd
    
    
    • 标号 prgman_tss
    定义
    ----------- 位于 内核程序 数据段 core_data ---------------
    ;程序管理器的任务信息 
     prgman_tss       dd  0             ;程序管理器的TSS基地址
                              dw  0             ;程序管理器的TSS描述符选择子 
    
    填写
    ----------- 位于 内核程序 start 标号后 ----------------
             mov [prgman_tss+0x00],ecx          ;保存程序管理器的TSS基地址 
    
             mov [prgman_tss+0x04],cx           ;保存程序管理器的TSS描述符选择子 
    

    回头看看第14章

    • 即在问:为什么不能像 第14章 那样指定返回到内核程序某个具体标号处

    第14章
    内核程序参考源码 https://www.jianshu.com/p/1e27f7e6b68e
    用户程序参考源码 https://www.jianshu.com/p/17a28f3dcda4

    • 第14章,用做返回点的具体标号如下所示:
    return_point:                               ;用户程序返回点
           ...
           ...  
     hlt
    
    • 第14章,用户程序进行返回的指令如下:
    call far [fs:TerminateProgram]
    
    • 第14章,任务从用户程序返回到内核程序的原理是什么?使用调用门(首先是,在内核程序写入了返回点的地址,然后是,加载用户程序时,在用户程序头部段重定位了SALT表)
    ----------- 代码位于 内核程序  数据段 core_data -----------------
    salt_4   db '@TerminateProgram'
            times 256-($-salt_4) db 0
            dd return_point
            dw core_code_seg_sel
    
    可以清楚地看到 这里的偏移地址就是  return_point
    
    ----------- 代码位于 用户程序 头部段 header --------------
    TerminateProgram db  '@TerminateProgram'
                         times 256-($-TerminateProgram) db 0
    
    加载用户程序时,就会完成 SALT的回写,不用在意这里占位用的0
    
    • 第14章的情况是,只有一个任务,即用户程序产生的任务,只有一次返回,来自用户程序返回到内核程序标号return_point处的返回;

    现在看看本章,第15章

    • 第15章的任务切换:TSS 记录 旧任务的 EIP 找到返回点(即执行任务切换前 执行到的下一条语句;


      TSS 记录 旧任务的 EIP 找到返回点(即执行任务切换前 执行到的下一条语句).png
    • 此时标号TerminateProgram的偏移地址正是子程序terminate_current_task的入口
    ----------- 代码位于 内核程序  数据段 core_data-----------------
             salt_4           db  '@TerminateProgram'
                         times 256-($-salt_4) db 0
                              dd  terminate_current_task
                              dw  sys_routine_seg_sel
    
    ----------- 代码位于 用户程序 头部段 header --------------
    TerminateProgram db  '@TerminateProgram'
                         times 256-($-TerminateProgram) db 0
    
    • 同样的,加载用户程序时,就完成了SALT的回写,只不过这一次的返回是返回到内核程序的子程序terminate_current_task处,再经由子程序自己做判断了;

    • 子程序 terminate_current_task的作用在于区分这是来自于call还是jmp指令的返回

    如果是call指令的返回需要一条`iretd`指与之搭配,再从TSS中恢复相关的状态;
    如果是jmp指令,直接找到TSS,中恢复状态;
    

    相关文章

      网友评论

          本文标题:[041][x86汇编语言]第十五章 终止当前任务 子程序 te

          本文链接:https://www.haomeiwen.com/subject/wnuwyftx.html