文章目录
一、实验主要内容
1、 内容1:整理源文件
重点总结:因为解决鼠标处理问题而导致程序变大了很多,所以准备整理程序
在bootpack.h里加上了函数声明,并在Makefile中将keyborad.obj, mouse.obj也补进去
2、 内容2: 内存容量检查(1)
重点总结:进行内存检查首先要搞清楚“内存有多大”、“内存地址范围”。 虽然可以使用BIOS检查内存容量,但调用BOIS会使asmhead.nas变长,同时BIOS版本不同,BIOS的调用方式也不同。因此决定自己检查内存。
(1)内存检查步骤
Step1:让486以后的CPU的高速缓存功能无效
为了提高执行速度,在每次访问内存时,都要将所访问的地址和内容存入高速缓存里。在每次写入数据时,要首先更新高速缓存信息,然后再写入内存。
(问题:为什么要使高速缓存的功能无效)
我们通过循环:”for(i=0; i<100; i++){}这样检查内存信息。 因为缓存控制电路发现,i被频繁的引用和赋值。所以在写入值不断变化时,不写入内存,而是在缓存内处理。这样写入和读出的不是内存,内存检查的结果也就不正确了。
386的CPU没有缓存,486的CPU就有缓存了。因此我们需要先查看CPU是否在486以上,判断是否需要关闭高速缓存。
Step2:两次反转检查内存
通过设计两次数值反转,如果其中一次数据结果不正确,则终止调查,并报告终止时的地址(错误地址)
(2)bootpack.c——memtest, memtest_sub
Memtest:
1、 内容说明
首先需要判断是否为CPU类型,若为486CPU则将EFLAGS寄存器的第18为AC标志位设置为0.(①②③)
另外还需要修改CR0寄存器中的标志位来禁止使用缓存。再获得内存大小后,重新恢复缓存设置。(④⑤)
2、 load_cr0, store_cr0
这两个函数不同使用C语言写,只能用汇编语言写,内容如下:
memtest_sub
1、内容说明
调查从start地址到end地址范围内,能够使用的内存的末尾地址。
(问题:为什么for循环中 I += 0x1000?)
由检测代码可知,每次反转是对4个字节的数据进行操作。也就是每次要检查4个字节,因此i+=0x1000(4)
2、函数优化
如果要检查全部的内存,速度就太慢了。因此改为”p = i+0xffc”,每次只检查末尾的4个字节(系统启动时内存已经被仔细检查过了)。
(3)结果展示