30天自制操作系统day10
一、实验主要内容
1、 内容1:内存管理
memman_alloc和memman_free能够以一字节为单位进行内存管理,不足之处是在反复进行内存分配和内存释放后,内存中会出现很多不连续的小段未使用空间,把man->free消耗殆尽。
因此,我们编写以0x1000字节(4kb)为单位进行内存分配和释放的函数,他们会把指定的内存大小按0x1000字节为单位向上舍入。
向下舍入
向上舍入
二进制数或者十六进制数可以通过与操作来向上或者向下取整,十进制却不可以,原因是十进制不能做与运算。
2、 内容2:叠加处理
能用于鼠标的叠加处理,也能直接适用于窗口的叠加,主要通过移动图层的方法实现鼠标指针的移动以及窗口的移动。
描述一个图层的结构体:
管理多个图层的结构体:
所占空间:
图层管理初始化:
取得未使用的图层:
设定图层的缓冲区大小以及透明色:
当设定高度之后,就需要对sheets[]进行重新排列,这样才能在之后正确的显示出来。
如果设定的高度比之前的高度低,那么就需要将之前的高度以上的图层向上移动一层,将所设定的高度插入。如果设定的高度是小于-1的,那么也就是要将该图层隐藏。
如果设定的高度比以前的高度高,就将以前高度到现在所设定高度的图层向下一层,为该高度的图层空出一层存放。如果以前的高度是-1,就将以上所有图层向上一层,已显示的图层要增加一个,即最高层的高度增加1。
sheet_refresh函数:从下到上描绘所有的图层(刷新)
sheet_slide函数:不改变图层高度而只上下左右移动图层
sheet_free函数:释放已使用图层的内存
我们准备了两个图层,分别是sht_back和sht_mouse,还准备了两个缓冲区buf_back和buf_mouse,用于在其中描绘图形。
make run
太棒了,成功了!
3、 内容3:提高叠加处理速度
因为鼠标指针最多只有1616=256个像素,harib07b原理是鼠标一移动就对整个画面进行刷新,也就是重新绘制320200=64000个像素,实际上我们只需要描绘移动前后的256*2=512个像素。
refreshsub函数用来提高sheet_slide的运行速度
这段程序所做的是:首先记住移动前的显示位置,在设定新的显示位置,最后只要重新描绘移动前和移动后的地方就可以了。
sheet_refresh函数:指定范围刷新
指定范围不是直接指定画面内的坐标,而是以缓冲区内的坐标来表示。这样子,HariMain就可以不考虑图层在画面中的位置了。
我们改动了refresh,也要相应的改动updown,这个改动只需要改动sheet_refresh(ctl)这部分
make run一下,速度确实快了很多!
4、 内容4:提高叠加处理速度(2)
改善refreshsub,提高速度。
这个程序,即使不写入像素内容或是只刷新图层的一部分,也要执行多次的if语句。
而对于刷新范围以外的部分,就算执行if语句,最后也不执行刷新,太浪费了。
我们对其进行改良,让bx在for语句并不是在0bxsize之间循环,而是在bx0bx1之间循环
(by亦是如此)
bx0和bx1都是从刷新范围“倒推”求得。
说明1:这行代码用于处理刷新范围在图层外侧的情况(刷新范围的一部分被鼠标覆盖)
在这里只需要重新描绘与鼠标重叠的一小块范围。
说明2:为了应对不同的重叠方式
这种情况下,bx0,by0可以顺利求取,但bx1和by1变得太大了(超过了图层的范围)
第三种情况:完全不重叠。此时完全不需要进行重复描绘
程序依然能正常运行,利用倒推bx0,bx1都是负值,说明1对其进行修正为0;说明2中bx1没有修正,还是负的,那么循环条件bx<bx1不成立,不循环,不会重复绘制。
make run 操作系统迅速运行
二、遇到的问题及解决方法
1、 描述问题1
对于鼠标的覆盖还有几种情况,类似图层的起始点x坐标在刷新范围的x范围之内,但y不在刷新范围的y范围之内?
解决:这种情况的话只需要结合前面第一种情况以及第二种情况即可。
2、 描述问题2
memman_alloc和memmam_free以一字节对内存进行管理,但是会出现很多不连续的小段未使用空间,作者通过以0x100字节为单位的方法解决,为什么?
解决方法:前面以一字节,由于某些为分配的内存区域太小,不能用了,产生了外部碎片。而后者则是采用固定大小的内存分区,当一个进程不能完全使用分给它的固定内存区域是就会产生内部碎片,当进程结束会返回的是一整块的空间,二不至于太小,相比于外部碎片很小导致不能使用会好得多。现在普遍采用的段页式内存分配方式就是将进程的内存区域分为不同的段,然后将每一段由多个固定大小的页组成。通过页表机制,使段内的页可以不必连续处于同一内存区域,从而减少了外部碎片,然而同一页内仍然可能存在少量的内部碎片,只是一页的内存空间本就较小,从而使可能存在的内部碎片也较少。
3、描述问题3
鼠标的移动是通过图层的移动来实现的,那么图层会不会移到外面去?updown函数是用来干嘛的?每次鼠标的移动都是图层的刷新,书上说的是320*200=64000个像素,不是大于这个数吗,因为有多个图层?
解答:图层的大小是不一的,上面的鼠标图层是最小的,所以移动鼠标并不会要求图标的图层移动到外面去;updown函数是用来设定图层的新的高度,当有图层的高度发生变化时,需要对整个图层重新进行排列,因为图层是一个序列;每次鼠标的移动都要对图层进行刷新,是对每一个图层从最低到最高的刷新,书上说的320*200=64000是整个画面的大小,但是根据重叠的原理,应该是每个图层都进行了重新的绘制,可以理解为大于这些像素,而后面通过描绘鼠标移动的两个位置也是要对每个图层的这两个位置都进行刷新,只是范围发生了改变,而这个范围则是以缓冲区内的坐标来进行表示,不用考虑在图层画面中的位置。
三、程序设计创新点
1、描述创新点1
设计一个窗口,显示此窗口
申请一个新的图层,申请缓冲区的内存,并且对缓冲区大小,透明色进行初始化
绘制窗口,即绘制我们定义的图层
make run
2、描述创新点2
当我们在窗口的X区域内用鼠标左键点击,窗口会消失
当鼠标按下左键,并且范围为X的区域,那么将该图层进行隐藏,显示出将窗口关闭的情形
3、 描述创新点3
当我们用鼠标左键点击左下方矩形的任务栏,我们绘制的窗口会显示出来
当按下鼠标左键,点击左下方的任务栏,将隐藏的图层高度上移,使其显示出来
4、 描述创新点4
窗口的关闭,大化,小化
窗口的移动
https://download.csdn.net/download/weixin_43979304/15320819?spm=1001.2014.3001.5503