30天自制操作系统第四天

操作系统实验日志4

学号 201708010402 姓名 徐冰娜 专业年级班级 智能1701
实验日期 2019.10.10 实验项目 第4天:C语言与画面显示的练习

30天自制操作系统第四天

  • 操作系统实验日志4
    • 一、实验主要内容
      • 1、内容1:C语言实现内存写入
      • 2、内容2:图案显示
      • 3、内容3:指针及其应用
      • 4、内容4:色号设定
      • 5、内容5:绘制矩形
      • 6、内容六:绘出操作系统的界面
    • 二、遇到的问题及解决方法
    • 三、程序设计创新点
      • 1、描述创新点1: 自己设计了一个简单的图案和动图。
    • 四、实验心得体会

一、实验主要内容

1、内容1:C语言实现内存写入

图案改变原理: VRAM是显卡内存,各个地址都对应着画面上的像素,我们可以改变其地址的值。INT 0x10画面模式下VRAM是0xa0000~0xaffff的64KB。

改变显存的值有两种办法:一是在汇编代码中通过mov指令改变地址中的值,二是在C语言中通过指针来修改。

①在naskfunc.nas中加一个函数_write_mem8供C程序调用

30天自制操作系统第四天_第1张图片

注释:汇编与C语言联合使用能自由使用的寄存器只有EAX,CX,EDX这三个,其他寄存器只读不能写。由于我们使用了32位寄存器,所以我们需要添加以下指令告诉我们的编译器我们是给CPU486用的:

在这里插入图片描述

②在C语言程序中通过指针修改地址中的值

30天自制操作系统第四天_第2张图片

解释:指针可以理解为是一个地址,指针指向的值就相当于是地址中的值,指针在我们现代的计算机中都是4个字节,大小不同的是指针所指向的类型。

注释:我们使用的编译器的标准只支持在函数的开始声明局部变量,否则会出错。

2、内容2:图案显示

①纯色图案:将我们地址中的每个值都设为相同的

在这里插入图片描述

30天自制操作系统第四天_第3张图片

②条纹图案:使每16个地址的值循环一遍

在这里插入图片描述

可以发现,i&0x0f的值每隔16次就反复一遍,而横向的想素值位320刚好为16的倍数,所以最后是条纹状。

30天自制操作系统第四天_第4张图片
如果使其值每隔15像素反复一次就成了:
在这里插入图片描述
在这里插入图片描述

3、内容3:指针及其应用

指针的两个应用实例:

在这里插入图片描述
在这里插入图片描述
解释:无论是*(p+i)还是p[i]都是将指针p向地址增大的方向移动i个位置,然后取这个地址中的值,其实我们以前学过的数组名本质上来说就是一个指针。

4、内容4:色号设定

这次使用的是320*200的8位颜色模式,色号用8位二进制表示,那么只能使用0-255。但是计算机表示颜色都是用#ffffff一类的数,就是RGB方式,为了随意指定0-255对应的颜色,可以用调色板。

调色板:它是一个只有256个表项的RGB颜色表,每一项是一个24为的RGB颜色值,也就是每8为代表这一种颜色的权重。用户可以随意指定0-255号数字所对应的颜色,也就是说我们也可以不必向上面步骤中那样改变内存中的值,而是直接改变数字对应的颜色值来迅速改变一个图像的颜色。

这次就直接使用16种颜色,并编上号码0-15:

30天自制操作系统第四天_第5张图片

这次的例子也是显示条纹画面(不过和前面不太一样),c语言中存在三个函数:

①主函数:

30天自制操作系统第四天_第6张图片

②调色板设定函数

30天自制操作系统第四天_第7张图片

这里定义了一个一维数组table_rej[16*3],写成16*3是为了说明有16种颜色,每一列分别代表R、G、B的值,数值越大,越亮,不同的亮度和颜色相调之后就会有不同亮度的颜色。

在set_palette函数中的0,15指的是0到15共16个色号。

注释: static类型的声明,从会汇编的角度来说减少了寄存器引用和赋值,相当于汇编指令DB,这样是代码的性能有所提高。

③使调色板的颜色设置好了可以应用到我们操作系统的函数。

调色板的访问步骤:

1.屏蔽中断(CLI);

2.设置调色板,将调色板号码写入0x03c8,按R,G,B顺序写入0x03c9,如果继续设定则继续写入;

3.如读出则将调色板号码写入0x03c7,从0x03c9按R,G,B顺序读取3次;

4.复原中断(STI)。

30天自制操作系统第四天_第8张图片

这里的0x03c9 是设备端口号, 屏蔽和恢复中断使用CLI和STI两个指令,在naskfunc.nas里面封装成了函数io_cli()和 io_stl(), CLI将中断标志置零, STI则是将中断标志置一.设置调色板的时候需要屏蔽中断,但不知道当前的状态是什么, 所以在CLI之前要保存中断标志的状态.中断标志保存在32位寄存器EFLAGS上, 由16位的FLAGS扩展而来。

30天自制操作系统第四天_第9张图片

上图是FLAGS 的示意图:中断标志位于第9位. 0位是进位标志, 2是奇偶标志, 4是辅助进位标志, 6是零标志, 7是符号标志…

使用指令PUSHFD和POPFD储存和恢复整个EFLAGS的状态,封装为io_load_eflags()函数和io_store_eflags(eflags)函数.

接下来是函数io_in8:

30天自制操作系统第四天_第10张图片

分析:首先,该函数利用栈来传递参数,例如第一个参数利用栈指针加4(为int类型大小),存入EDX,然后第二个参数在上一个基础上+4,既ESP+8,存入EAX。然后,利用专门的端口读写函数out DX,AX(将AX里面值写入端口号为DX的设备);

CPU管脚与内存相连,CPU就只能完成计算和存储功能,但实际上,CPU还要对键盘输入有响应,通过网卡从网络取得信息,通过声卡发送音乐数据,向软盘写入信息等。所以他们也要连到CPU上,既然CPU和设备相连,那么就有向这些设备发送电信号,或者从这些设备中取得信息的指令。向设备发送电信号的指令为OUT指令,从设备取得电气信号为IN指令。

30天自制操作系统第四天_第11张图片

5、内容5:绘制矩形

30天自制操作系统第四天_第12张图片
30天自制操作系统第四天_第13张图片
30天自制操作系统第四天_第14张图片
这一部分比较简单,就不做解释了

6、内容六:绘出操作系统的界面

这一部分主要就是利用绘制矩形的函数,拼接而成的。

简单举两个例子,同一颜色的框相互对应:

30天自制操作系统第四天_第15张图片

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

1.描述问题1:在汇编函数write_mem8(int addr, int data)中,作者写的是参数放在了ESP的上面,但是在以前学过的知识中,参数是存放在Ebp的上面,不明白为什么

解决方法:这个问题是我提出来的,是想到了以前的知识,函数的栈的ebp+4位置存放的是返回地址,然后ebp+8是从做开始第一个参数,若参数是4个字节,ebp+12存放就是第二个参数,然后以此类推。可是这次确是在esp上面,然后我问了一些同学的意见,有人说是该汇编函数的栈和我们以前学的不一样,有同学说这次传递参数不是用的寄存器而是用的栈传参,而我们以前用的是寄存器传参,传参的方式变了。然后经过思考,感觉这两种说法都不值得推敲,具体原因就步列出来了。最后我得出的结论是,该汇编代码中的esp是调用者的栈中的esp,不是被调用函数的esp,这样就说的通了,也和以前学过的知识也相符。

2.描述问题2:在set_palette函数中,为什么要将每个颜色的值除以4?

30天自制操作系统第四天_第16张图片

最开始看到这个除以4,我首先想到的是在opencv在处理像素时,会通过一个简单的除法来进行颜色空间缩减以提高性能,但是重新读了代码后,知道不是一回事,将除数的值增大,色彩的亮度会变暗,如果不设除数,后8种色彩很难与黑色分辨,接着我去查阅了一些资料:

电脑屏幕上的所有颜色,都由这红色绿色蓝色三种色光按照不同的比例混合而成的。一组红色绿色蓝色就是一个最小的显示单位。屏幕上的任何一个颜色都可以由一组RGB值来记录和表达。每三个确定一个颜色,分别代表红绿蓝的分配比例,分配的越多,代表的颜色就越深。这样就似乎明白作者为什么说只要16种颜色了。确实,16*16=256,
我们只要修改这个/号除的数,就可以得到不同的颜色。就不进行除法操作那个来说,就是调色板的原色,而进行了除法操作的都是相应色调降低了的。色调是各种图像色彩模式下原色的明暗程度,级别范围从0到255,共256级色调。例如对灰度图像,当色调级别为255时,就是白色,当级别为0时,就是黑色,中间是各种程度不同的灰色。在RGB模式中,色调代表红、绿、蓝三种原色的明暗程度,对绿色就有淡绿、浅绿、深绿等不同的色调。色调
是指色彩外观的基本倾向。在明度、纯度、色相这三个要素中,某种因素起主导作有用,可以称之为某种色调。实验的结果似乎是证明的原色的明暗程度的改变。

3.描述问题3:为什么在设定调色板的时候要禁止中断?

我没有查到具体的解释,只查到了在什么情况下需要关闭中断:

1、操作的对象是共享资源(全局变量),其他任务可能在整个操作流程中打断你的操作,并且会更改你的全局变量,最终会引起非常严重的后果的情况下需要关中断。

2、当任务在执行对时序要求非常高的操作,因为被其它任务中断浪费了很多时间,当回来的时候错过了dead
time,最终导致操作失败。

我只能推测在向端口写入信息的时候,要通过禁止中断,防止因中断而导致向端口写入了其他信息。

三、程序设计创新点

1、描述创新点1: 自己设计了一个简单的图案和动图。

这个小太阳会逐渐的升起
30天自制操作系统第四天_第17张图片

关键代码如下:

30天自制操作系统第四天_第18张图片

30天自制操作系统第四天_第19张图片

我的逻辑很简单,我不想自己手动一个像素一个像素的去填色,而是通过一些简单几何图形的方程实现颜色的填充,比如圆的方程是(x-x0)^2 +(y-y0)^2 <= r^2,只要坐标的方程满足,就可以将圆填满。动图的实现是不断改变圆心的位置,很次改变增加一个空的for循环作为延迟。

四、实验心得体会


本次实验我学会了更改操作系统显示的两种方法,有直接更改显存中的值和调用调色板两种方式;我还学到了一些关于色彩的知识;然后我还通过实践更改了我的显示画面,做了一个简单的动图和简单图形的填充。感觉比较有乐趣。本周我们还学习了用rust语言编写简单的操作系统,两种实现的原理差不多,都是向一段特定内存中写入信息,结合前段时间学习的启动区知识,现在感觉对操作系统已经多了很多了解,自己也越来越有兴趣去学习接下来的知识。但是很苦恼的是,作者给的网站有很多已经失效,因此我去查资料的时候难度很大,很多细节,很多问题都查不到详细的资料,只能得到一些模棱两可的答案,希望在日后的学习中,这些问题可以得到解决。

你可能感兴趣的:(30天自制操作系统第四天)