[063][x86汇编语言]第16章|[063][x86汇编语言]第16章 本章习题一 思考与尝试

学习笔记

《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
本章习题 习题一
1、代码清单16-2(c16.asm)的第47行是通过调用门进入系统核心显示字符串的指令:47 call far [PrintString],请以该指令的执行过程为例,说明为什么必须将系统核心映射到每个任务的4GB地址空间内才行?
不太理解题意,下面是我的尝试和思考
  • 1、打开bochs,调试到用户程序的这一条语句47 call far [PrintString],截图如下:

    [063][x86汇编语言]第16章|[063][x86汇编语言]第16章 本章习题一 思考与尝试
    文章图片
    call far [PrintString].png
  • 2、从截图中可以看见,这时候显示的是callf ds:0x00000010,其中数据0x00000010是用户程序中标号PrintString的偏移量,标号处此时已经被回填了调用门的选择子和偏移量;
  • 3、题目在问为什么必须将系统核心映射到每个任务的4GB地址空间内才行?,我对这个问题的理解是,这个问题等价在问此时、处理器是如何理解 0x00000010的?
  • 4、首先,0x00000010很明显是一个线性地址,遇到线性地址,处理器就要按照段部件-高10位、中10位、低10位的格式来读取,然后去页目录表(物理地址存在寄存器CR3中)、页表找到对应的物理页以及偏移处;
  • 5、那么,使用命令creg就可以查看当前页目录表的物理地址(即,页目录表(user)CR3=0x000000141000

    [063][x86汇编语言]第16章|[063][x86汇编语言]第16章 本章习题一 思考与尝试
    文章图片
    CR3=0x000000141000
  • 6、在内核程序中的代码运行后达到如下的效果:
每个任务都有自己的页目录表以及页表, 页目录表的前半部分对应着任务自己虚拟地址空间的前2GB(0~2G)(低端1M) 后半部分则映射到内核的页表(2~4G)(高端1M);- 当任务在自己独立的局部空间工作时,使用它自己的页表; - 当任务请求系统服务时,用的则是内核的页表,访问的是内核的代码和数据;

  • 7、调用门描述符的选择子就是内核公用例程段的选择子(sys_routine_seg
    通过https://www.jianshu.com/p/c251257329fe 已经被映射到高端1MB了,那么,使用这个选择子找到的段描述符中的段基地址就是0x8........开头的指向高端1MB的线性地址;
需要修改与内核有关的段描述符 ; #公用例程段 or dword [es:ebx+0x28+4],0x80000000

[030][x86汇编语言]第十四章 调用门描述符的格式 https://www.jianshu.com/p/268fa4fd21a0
[055][x86汇编语言]16.3.2 使用高端1MB线性地址0x80000000~0x800FFFFF
https://www.jianshu.com/p/c251257329fe

[063][x86汇编语言]第16章|[063][x86汇编语言]第16章 本章习题一 思考与尝试
文章图片
0x8........开头的指向高端1MB的线性地址
  • 8、如果,不将系统核心映射到每个任务的4GB地址空间内,那么,当任务调用内核服务时,地址转换将无法进行,因为任务的页目录表和页表没有登记内核所占用的那些物理页面;
  • 9、现在,用户程序的页目录表(user)物理地址是0x000000141000,从这个物理地址处读出来的页目录表,按照过程[create_copy_cur_pdir]的实现规则来看,是将内核的页目录表复制而来的,自然就会有登记内核所占用的那些物理页面。
知识点复习
  • [055][x86汇编语言]16.3.2 使用高端1MB线性地址0x80000000~0x800FFFFF
https://www.jianshu.com/p/c251257329fe
  • [057][x86汇编语言]第16章 源码分析 过程[create_copy_cur_pdir]:复制 页目录表(core)到 页目录表(user)
【[063][x86汇编语言]第16章|[063][x86汇编语言]第16章 本章习题一 思考与尝试】https://www.jianshu.com/p/9bc184361aac

    推荐阅读