有了前文底层汇编的铺垫,本章主要是过渡到C语言的编写,先由最基础的写内存,绘制基本图形开始。
一 C语言写内存
前文用汇编语言构建了一个写内存的函数write_mem8:
_write_mem8: ; void write_mem8(int addr, int data);
MOV ECX,[ESP+4] ; [ESP+4]にaddrが入っているのでそれをECXに読み込む
MOV AL,[ESP+8] ; [ESP+8]にdataが入っているのでそれをALに読み込む
MOV [ECX],AL
RET
这边首先考虑用C语言实现写内存的功能:
void io_hlt(void);
void HariMain(void)
{
int i; /* 変数宣言。iという変数は、32ビットの整数型 */
char *p; /* pという変数は、BYTE [...]用の番地 */
p = (char *) 0xa0000; /* 番地を代入 */
for (i = 0; i <= 0xffff; i++) {
p[i] = i & 0x0f;
}
for (;;) {
io_hlt();
}
}
这边注意两个问题:
【1】这边为什么用p[i]来写数据呢?
其实C语言中的*和汇编语言中的[]有类似的地方,都是一种取址操作符。即:
汇编符号[] ≈ C语言符号*
而C语言中的[]也是C语言中的*的另一种写法,例如p[i]与*(p+i)意思相同。这样说明就好理解了。
【2】这边C语言写内存,即往0xa0000地址对应的偏移位写数据。那为什么是0xa0000这个地址呢?
因为[VRAM]里保存的是0xa0000。在电脑的世界里,VRAM指的是显卡内存(video RAM),也就是用来显示画面的内存。这次[VRAM]的起始值是0xa0000是因为我们设置的INT 0x10模式,该画面模式下,[VRAM]是0xa0000----0xaffff的64KB。具体设置参考asmhead.nas里面的相关设置:
二 调色板颜色初始化
调色板的相关配置如下所示:
其中,注意三点:
【1】屏蔽中断CLI和开启中断STL只能在汇编中做:
【2】数据从端口的写入也只能在汇编中做:
【3】EFLAGS是用来存储进位标志和中断标志等标志的32位寄存器。对这个寄存器的操作只能通过入栈出栈的操作来完成,不能直接赋值:
三 绘制矩形(结合写内存与颜色)
当前调用BIOS中断命令INT 0x13,设置显卡模式为VGA图形模式,320*200*8位彩色模式。
所以对应的像素坐标(x,y)的计算应该是:
[VRAM]=0xa0000 + x + y*320
由此往对应像素点(内存)中填充设定颜色,即可绘制矩形图案,绘制矩形函数如下:
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
int x, y;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++)
vram[y * xsize + x] = c;
}
return;
}
基于此,画了几个矩形,已经初具操作系统的外观了。最终的效果如下: