<自己动手写操作系统>第三章pmtest7源码解析——检测系统内存

本文详细介绍了如何根据内存容量恰当地分配页表,并通过分析分页机制的理论基础和代码实现,优化了内存使用效率。主要内容包括获取内存分布信息、解析代码结构、理解堆栈操作以及内存寻址原理等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

摘要:pmtest6.asm中,我们已经初步接触了分页机制,但是很显然,上述分页机制浪费比较严重,而且没有体现应有的用处。本节,我们主要介绍如何根据内存容量,恰当地分配页表。

一、理论基础

1.如何获取内存分布信息?

获取内存,需要用到dos下的int 15h中断,可以参考这里: http://blog.youkuaiyun.com/trochiluses/article/details/20078161

二、代码剖析

pmtest7中,我们需要对代码结构作出一定的调整:

1、定义库文件:

在库文件lib.c中,定义如下函数:DispALDispReturnDispIntDispStr 我们仍然采用分段的方式来分析比较陌生的代码: 另外,我们定义了szPMMessage,接着,有这样一句汇编: push szPMMessage 这句对堆栈的改变是多少? 你要知道,这是push in stack的是地址,而不是具体的字符串。

2.DispIntDispStr的原理有很大的不同:

1)Dispint中,堆栈中存放的直接是要显示的整数,但是,有几点需要注意 mov eax,[esp+4]中,采用的是ss寻址,而不是ds寻址;为什么esp需要+4,是因为经过call指令之后,堆栈顶部存放的不再是刚刚入栈的整数,而是EIP!!! 2DispStr中,堆栈中存放的是字符串的地址,同样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
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值