30天自制操作系统day4
一、实验主要内容
1、 内容1:用C语言实现内存写入
因为想要在画面上显示东西的话,需要向内存VRAM中写入东西。但是C语言没有直接写入指定内存地址的语句,需要用汇编语言创建一个有这种功能的函数。
对naskfunc.nas进行修改,添加_write_mem8函数
还给naskfunc.nas增加了一行INSTRSET指令,用来告诉nask“这个程序是给486用的”。
电脑的CPU家谱(英特尔系列)
8086->80186->286->386->486->Pentium->PentiumPro->PentiumII->PentiumIII->Pentium4->……
在for循环语句内调用write_mem8函数
此时参数指定数字存放在内存里,第一个数字存放地址[esp+4],第二个数字存放地址[esp+8]……
make run
画面显示为白屏,因为VRAM全部写入了15,全部颜色第15号为纯白,所以为白色
2、 内容2:条纹图案
通过“或”(OR)运算让特定位变1;
通过“与”(AND)运算让特定位变0;
通过“异或”(XOR)运算让特定位反转;
这次用的是与运算,低四位保留,高四位变0,每隔16个像素,色号反复一次
make run
3、 内容3:指针及指针应用
其实C语言有写入内存的语句
char *p
*p= i & 0x0f
替代语句
write_mem3(i , I & 0x0f );
C编译器有类型的区分
char *p; 用于BYTE类地址
short *p; 用于WORD类地址
int *p; 用于DWORD类地址
make run
另外两种写法为
4、 内容4:色号设定
对bootpack.c程序进行解释:
主函数HariMain里只是增加一行调用调色板装置的函数
函数init_palette声明一个常数table_rgb
像汇编语言中用DB指令代替RESB指令那样,在C语言也有类似的方法,那就是在声明是加上static
char型变量有三种模式,signed,unsigned,未指定型;signed用于处理-128127的整数,unsigned能处理0255的整数,未指定型由编译器决定是signed还是unsigned。
set_palette这个函数用来多次调用io_out8;
向设备发送电信号的是OUT指令,从设备取得电气信号的是IN指令;
CLI,是将中断标志置为0的指令,STI是要将中断标志置为1的指令;
当CPU遇到中断请求时,是立即处理中断请求(1),还是忽略中断请求(0),由终端标志决定
FLAGS是存储进位标志和中断标志等的寄存器
o_store_eflags将eflags的值代入EFLAGS,中断标志就恢复为原来的值
make run
条纹的图案没有变化,颜色改变了
5、 内容5:绘制矩形
像素坐标(x,y)对应的VRAM地址按下式计算
0xa0000+x+y*320
根据上式计算像素地址,往该地址的内存里存放某种颜色的号码,那么该像素位置就出现对应颜色。这样画出一个点,继续增加x,画出一条水平直线;在向下循环(y),即可组成一个矩形。
make run
6、 内容6:修改图案
修改HariMain程序
make run
由于像素太少的缘故,任务条有点大
二、遇到的问题及解决方法
1、描述问题1
1、 为什么在该式中要除以4
解决方法:函数set_palette() 中设置调色板颜色时,“io_out8(0x03c9,rgb[0]/4);”这句中之所以除以4是因为8位彩色模式下指定R、G、B三种颜色的值时只能用6位来指定,所以init_palette(void) 中的table_rgb中的值用来指定RGB颜色的值时,只使用了高六位。笔者做的实验中,如果去掉除以4不写的话,从亮灰色往后的颜色就变成了黑色,具体原因不详。
2、描述问题2
bootpack.c中主函数名不能更改
解决方法: 可能作者将HariMain这个主函数名嵌入到编译器中,总之不能改
三、程序设计创新点
1、 描述创新点1
修改部分代码,使得绘制图形为数字图案
效果如下图所示
2、 描述创新点2
修改代码,使输出图形形状为网状型
30天自制操作系统1~15天日志:https://download.csdn.net/download/weixin_43979304/15320819?spm=1001.2014.3001.5503