摘要:在pmtest6.asm中,我们已经初步接触了分页机制,但是很显然,上述分页机制浪费比较严重,而且没有体现应有的用处。本节,我们主要介绍如何根据内存容量,恰当地分配页表。一、理论基础
1.如何获取内存分布信息?
获取内存,需要用到dos下的int 15h中断,可以参考这里: http://blog.csdn.net/trochiluses/article/details/20078161二、代码剖析
在pmtest7中,我们需要对代码结构作出一定的调整:1、定义库文件:
在库文件lib.c中,定义如下函数:DispAL,DispReturn、DispInt、DispStr 我们仍然采用分段的方式来分析比较陌生的代码: 另外,我们定义了szPMMessage,接着,有这样一句汇编: push szPMMessage 这句对堆栈的改变是多少? 你要知道,这是push in stack的是地址,而不是具体的字符串。2.DispInt和DispStr的原理有很大的不同:
1)Dispint中,堆栈中存放的直接是要显示的整数,但是,有几点需要注意 mov eax,[esp+4]中,采用的是ss寻址,而不是ds寻址;为什么esp需要+4,是因为经过call指令之后,堆栈顶部存放的不再是刚刚入栈的整数,而是EIP!!! 2)DispStr中,堆栈中存放的是字符串的地址,同样ebp也是相对ss进行寻址的 3)关于内存寻址符号[]? [esi]\[gs:edi]\[esp] 注意,内存寻址实际上采用的基地址+变址寻址。语法和对应的实际地址如下 [esi]---> ds:esi [idata]----->ds:idata [esp]-------->ss:esp [ax]------>error!! stosb------>es:edi lodsb------->ds:esi 当然,也可以直接指定段寄存器[gs:edi]3.读取内存信息,确定内存上限的原理是什么?
注意:进行内存信息读取之前,我们需要明白,BIOS读取的内存地址都是64b的,所以,我们只使用低32位就可以了。另外,我们读取到的内存信息,并不是按照基地址从小到大排列的,所以我们要用 if(BaseAddrLow + LengthLow > MemSize) MemSize = BaseAddrLow + LengthLow; 这一句来检测内存上限(注意,这是内存地址的上限,而不是内存大小的上限)4.理清代码跳转结构
s16code:init segment info,get meminfo, jmp to protect model:s code32 scode32:display szpmmessage,display title,display memsize, setuppageing,jmp code16 normal
<自己动手写操作系统>第三章pmtest7源码解析——检测系统内存
最新推荐文章于 2020-06-26 19:55:27 发布