一、实验主要内容
1.用C语言实现内存写入
关键代码:
重点内容:
- 与write_mem8链接是在其函数名前面加“_”;
- RET指令的作用是从该段子程序返回;
- 指定内存地址的地方,如果用16位寄存器指定[CX]或[SP]会出错,除指定地址外,还可以指定寄存器并向寄存器加或减去一个常数。
- 当与C语言联合的时候,可以自由使用的寄存器如下:EAX,ECX,EDX。
- INSTRSET指令:告诉nask“这个程序是给486(CPU型号且为32位)使用的”,只有这样EAX才会被解释为寄存器的名字。
- For循环的终止条件计算:0xa0000+320x200,每次data赋值为15写入VRAM的目的是显色白色。
- 运行截图:
- 条纹图案
关键代码:
重点内容:
- i & 0x0f 的作用是因为:使得i的特定位置为0,从而可以实现有规律的颜色切换。
- 让特定位置变1则需要或运算,或运算、与运算都是按位运算。
- 异或运算规律总结:相同则为0,相异则为1。
- 运行截图:
不仅辣眼睛,还贼丑!
- 挑战指针、指针的应用
关键代码:
重点内容:
- 使用 *i = i & 0xf ,*i是指针变量,存储着某个值的地址,因此可以理解成一根指向某个地址的针,称之为指针。
- 替换后make run 运行会报类型错误,引起这样的原因是*i指定的内存为BYTE还是WORD不确定。从根本上说,是*i没有指定数据类型,但加上数据类型后即可正常运行,如char *i,声明*i为char类型,亦即BYTE。
- BYTE类指针:char *p ;WORD类指针:short *p;DWORD类指针:int *p;但不管是何种类型,在汇编语言中均用4字节的寄存器来指定,因此可以认为它们都是4字节的。
- 经过(2)步骤后make run 运行出现警告,引起的原因是i是整数直接代给了指针变量,解决办法将i强制转换成指针类型:(char *)i。
- 运行后仍是辣眼睛且巨丑的条纹!由于过于辣眼睛不再贴图!
- COLUMN-2:只要使用类型转换,的确可以不使用指针之类的方法,意思就是不需要特意声明指针类型的变量,通过类型转换就可以了,单个人推荐先声明指针变量,这样就可以避免复杂的表达式。
- COLUMN-3:p = (char *)i ,*p = i & 0x0f 与 *p = i & 0x0f ,p = (char*)i 的区别:前者是正确的写法,后者是错误的,后面的写法会导致p是一个随机值,数据会被写入未知的地址,引起的后果非常严重。
- 变量一定要声明才可以使用和进行各种操作。
- Char *p,p的理解:一个很方便的理解就是看作声明了:char类型的*p和p这两个变量,一个是指针,一个是普通变量。
(10)COLUMN-4:p[i]本质上讲是数组某个元素的地址,其指针形式是:*(p+i),p是数组的首地址,因为数组名常用作数组的首地址,地址是连续的,因此p[i]可以表示为*(p+i)。
- 色号的设定
关键代码:
重点内容:
- 对不同的颜色进行编号的方法称为调色板;
- 绘制一个操作系统模样的画面需要用到以下16种颜色:
- char类型的变量有3种形式:signed型、unsigned型、未指定型,未指定型的意思是当没有说明是signed或unsign时,由编译器决定它是signed或unsign。
- io_out8()函数的作用是往指定装置传送数据,8是8位真彩色。
- 如何获得端口号0x03c9:根据调色板的访问步骤,设定调色板:先将调色板的号码写入0x03c8,然后按照RGB的顺序写入0x03c9。取出调色板状态:先将调色板号码写入0x03c7,再从0x03c9读出。
- CLI与STI:CLI负责将中断标志置为0的指令,STI则是将中断标志置为1的指令。中断标志位的作用是决定cpu处理该请求还是忽略该请求。
- EFLAGS:由16位FLAGS寄存器扩展成32位,其结构如图:
不同的位置代表不同的标志位,如0号位置是进位标志。因为不像进位标志那样可以通过JC或者JCN来判断,当遇到中断标志,必须先读入EFLAGS再去检查9号位置的值。
- PUSHFD指令是“push flags double-world ”的缩写,将标记值按照双子压入栈。POPFD是将标志位按双字出栈。
- 关于栈的扩展:栈是一种基于数组实现的数据结构,只允许访问栈顶元素,数据是先进后出的规则,进栈过程称为push,出栈称为pop。
- 绘制矩形
关键代码:
重点内容:
- VRAM地址计算公式:
- 画出图像的原理:将颜色代码写入VRAM后,就画出了一个点,线条无非就是无数点,改变点的位置就成一条线了,改变y的位置,自然而然线条就组成图像
- 遇到的问题及解决方法
为什么这里要除4?
VGA显示模式只支持6位的颜色,而我们是采用8位的16进制来表示颜色,为了更好的适配VGA显示,需要将8位的颜色右移2位,也就是除4。
三、程序设计创新点
(1)绘制自定义图案:
关键代码:
运行截图:
别看丑,还是很难画的!
(2)如何在界面上判断是那段代码绘制的:
关键代码:
比如要判断左下角这个矩形是由哪段代码绘制的,首先根据颜色找到对应的,比如这个是灰色对应15号颜色,15号颜色的那个编号是
然后找到颜色是这个的代码段,再根据它在界面的位置,比如它的x比较小,大概2-5的范围,这个时候就可以定位置5-7行代码,再根据y坐标比较大这个条件,推得是第七行代码绘制了左下角这个矩形的横线,总之就是看开始的点与结束的点xy之间的关系,x不变y变说明绘制的是横线,x不变y变则绘制的是横线,通过改变x或y就可以绘制出无数的线,最后组成一个矩形!