30天自制操作系统概念第八天日志

一、实验主要内容

1、 内容1:鼠标解读(1)

前一天已经实现了从鼠标中取得数据,因此这一天就是解读之前取得的数据,让鼠标能够动起来。
首先对HariMain函数进行修改,将读鼠标得到的最初的0xfa舍弃。将之后的鼠标传送的3个字节一组的数据,使其显示在屏幕上。
为什么要舍弃0xfa?
因为鼠标已经激活,不需要这个显示的数据了。

在这里插入图片描述
第一个字节和按键有关,第二个字节和左右移动有关,第三个字节和上下移动有关。
在bootpack.c文件的入口函数中,我们还是先检测键盘的缓冲区有没有数据,当键盘中断都处理完了再处理鼠标中断产生的数据
在这里插入图片描述
当一组数据的三个字节数据都存到了mouse_phase数组中,就向屏幕输出
运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行结果分析: “08”部分的0只会在0-3范围内变化,之移动鼠标,08部分的“8”那一位不会发生任何变化,只有点击鼠标才会变化。上述第二组数据与鼠标的左右移动有关系,第三组数据与鼠标的上下移动有关系。

2、 内容2: 稍事整理

在这里插入图片描述
在这里插入图片描述
然后通过一个函数对鼠标数据的处理进行整合:
在这里插入图片描述
判断三个数据是否都准备好
在这里插入图片描述

3、内容3:鼠标解读(2)

①结构体增加变量描述鼠标的移动情况
在这里插入图片描述
②增加对第一字节的检查:判断前4位是否在0-3之内,后四位是否在8-F之内
如果这个字节的数据不在以上范围内,它就会被舍去。
在这里插入图片描述
0xc8=11001000,前四位可以检测是否0~3范围,如果大于3,则进行与运算后第一位不为0;
后四位可以检测时候8~F范围,如果是,则第一个1与运算后为1,即运算后为0x08
进行检测的原因:
鼠标连线偶尔也会有接触不良、即将断线的可能,这时就会产生不该有的数据丢失,这样一来数据会错开-一个字节。数据一旦错位,就不能顺利解读,后面的数据就都“错位”。而如果添加上对第-字节的检查,就算出了问题,鼠标也只是动作上略有失误,很快就能纠正过来,所以加上了这项检查。
③获取鼠标的按键信息
在这里插入图片描述
因为鼠标的按键信息保存在3-0位上,且值在8-F之间,他们的第3位都为1,所以只需要取后三位就可获得鼠标的按键信息。
④在第三阶段对数据进行处理:根据鼠标的移动情况获取鼠标的相对坐标
在这里插入图片描述
只是移动鼠标的情况下,后四位无关,所以与0;
0001,0011(1,3)和0x10与,鼠标左移;
0011,0010(2,3)和0x20与,鼠标下移;(本来上移,因后面对y进行取反操作)
结果显示如下:

在这里插入图片描述
⑤显示部分:用字母位置把初始的小写l\r\c变成大写L\R\C表示按下鼠标的左\右\中
在这里插入图片描述
make run
移动鼠标
在这里插入图片描述
点击鼠标
在这里插入图片描述

4、内容4:移动鼠标指针

在这里插入图片描述
可以得到鼠标的坐标范围在[(0,0),(304,184)]之间,即320-16,200-16。
从代码中可以看出,关于鼠标坐标的计算不是时刻连续的,而计算的是更新之后的坐标。
make run
在这里插入图片描述
晃一晃鼠标
在这里插入图片描述
鼠标接触到屏幕下方的任务栏,会变成这样
在这里插入图片描述

5、 内容5:通往32位模式之路

在这里插入图片描述
等同于下面的C程序
在这里插入图片描述
主PIC和从PIC的中断关闭了
新指令NOP,让CPU休息一个时钟长的时间。
因为CPU运行的速度远远高于IO设备的运行速度,所以先让CPU休息1个时钟的时间,等待IO操作的完成,不然CPU要一直轮询
如果当CPU进行模式转换时进来了中断信号,就会有麻烦。而且后来还要进行PIC的初始化,初始化时不允许中断。所以最后要把中断全都屏蔽掉。
在这里插入图片描述

这次输出0xdf要完成的功能是让A20GATE信号线变成ON的状态。这条信号线能使内存的1MB以上的部分变成可使用状态。

在这里插入图片描述
CR0寄存器:即control register 0,只有操作系统可以使用。
保护模式的段寄存器解释不是16倍而是能够使用GDT。这种模式下应用程序既不能随便更改段的设定,又不能使用操作系统的专用段,操作系统受到CPU的保护。保护模式分带保护的16位模式和带保护的32位模式两种,我们使用带保护的32位模式。
进入保护模式以后,段寄存器的意思也变了(不是×16再加了)除了CS(CS变了会造成混乱)以外所有段寄存器的值都从0x0000变成了0x0008(相当于gdt+1的段)。

memcpy函数:将一块内存的数据复制到另一块内存中
memcpy(转送源地址,转送目的地址,转送数据大小(以双字为单位所以数据大小用字节数/4来指定))
在这里插入图片描述
意思是从bootpack的地址开始的512kb内容复制到0x00280000号地址,就是将bootpack.hrb复制到0x00280000号地址。
在这里插入图片描述
从0x7c00复制512个字节到0x00100000(DSKCAC),就是将启动扇区复制到1MB以后的内存。
在这里插入图片描述
将始于0x00008200的磁盘内容,复制到0x00100200。转送数据大小计算:cyls值为10,表示10个柱面;512表示一个扇区容纳的字节数;18表示一个盘面共18个扇区;2表示一个柱面有两个磁头。它需要减去启动扇区的那一部分长度。(为什么是0x8200开始,请看最后我的内存使用整理)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码解析:这段代码将执行所必需的数据传送过去。EBX代入的是BOTPAK。JZ是条件跳转指令,根据前-个计算结果是否为0来决定是否跳转。在这里,根据SHR的结果,如果ECX变成了0,就跳转到skjp那里去。在harib05d里, ECX没有变成0,所以不跳转。 最终,memcpy将bootpack.hrb第0x10c8字节开始的0x11a8字节复制到0x00310000号地址去。最后将0x310000代人到ESP里,然后用一个特别的JMP指令,将2*8代人到CS里,同时移动到0x1b号地址。这里的0x1b号地址是指第2个段的0x1b号地址。第2个段的基地址是0x280000,所以实际上是从0x28001b开始执行的。这也就是bootpack.hrb的0x1b号地址。这样就开始执行bootpack.hrb了。

在这里插入图片描述
IN AL,0x64:读端口 0x64 到 AL.
读端口0x64就是读8042的状态寄存器(一个8bit的只读寄存器),bit_1为1时表示输入缓冲器满,为0时表示输入缓冲器空。要向8042写命令(通过0x64端口写入),必须当输入缓冲器为空时才可以。所以当CPU从设备号码读取的倒数第二位是0,键盘控制电路才准备好,如果不为0,就跳到waitbdout不断循坏。
在这里插入图片描述
ALIGNB指令:于对指令或者数据的存放地址进行对齐
ALIGNB 16:要求下面的起始地址是16的倍数

“纸娃娃系统”的内存分布图
在这里插入图片描述

二、遇到的问题及解决方法

1、 描述问题1 为什么会出现鼠标指针“吃掉”任务栏的现象

因为每次鼠标移动前都要清除掉目前的鼠标,而作者的做法是让背景色即暗浅蓝覆盖指针,所以在上面背景色为暗浅蓝的时候看起来是移动正常的,但是移动到了下面之后,再加上鼠标本身背景色就会让下面鼠标所在的地方变成暗浅蓝。

2、 描述问题2 为什么bootpack的地址就是bootpack.hrb?

在这里插入图片描述
在这里插入图片描述
可以看到bootpack标签在asmhead.nas的最后面

在这里插入图片描述
而bootback.hrb是拼接在asmhead.bin后面的,所以指的就是bootback.hrb的首地址。

三、程序设计创新点

1、描述创新点1,改善鼠标指针“吃掉”任务栏的现象

因为主函数中的for循环每循环一次,就会用一个绿色的方块对上一次鼠标所在的位置进行颜色的恢复,所以我们可以用一个256大小的数组保存上一次鼠标所在的位置的颜色,然后用这个数组去恢复它的值。
在这里插入图片描述
在这里插入图片描述
在计算完鼠标的左上角的坐标后,在显示鼠标之前,保存下来鼠标将要覆盖的位置的值:
在这里插入图片描述
在这里插入图片描述
最后需要看我们用来显示鼠标的函数putblock8_8,鼠标的颜色是存到了mcursor数组中,而鼠标的初始化函数将鼠标的背景设置成了绿色,所以应该在鼠标初始化的时候不设置背景颜色。
在这里插入图片描述
在这里插入图片描述
最后的结果:
在这里插入图片描述

2、描述创新点2,改善鼠标指针“吃掉”任务栏的现象

上图会出现黑色方块的原因是没有对我们开辟的数组的256个像素初始化,因该给该数组初始化为当前鼠标该有的背景色,为0x008484.
在这里插入图片描述
结果如下所示:
在这里插入图片描述
总结一下步骤:

  1. 开辟一个大小为256的数组,用于保存鼠标下一次显示位置的显存信息;
  2. 给数组初始化为当前鼠标该有背景色,为0x008484, 256个像素全部初始化
  3. 恢复当前鼠标位置信息,即将数组数据赋给当前鼠标像素
  4. 将下一次鼠标显示位置的显存信息保存在数组里,覆盖原来的值
  5. 显示鼠标下一步的位置
  6. 重复3,4,5步骤

四,实验心得体会

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SIR怀特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值