第四天
先看看今天要做个啥,make run一下最后的版本
有显示了,但是好像没有鼠标
第一节
关于参数存放地址为什么是[ESP+4]和[ESP+8]可参考30天自制操作系统:第四天 C语言与画面显示的练习_nepu_bin的博客-优快云博客
关于C语言中直接写指定内存地址的语句
#include "stdio.h" int main() { int *p;//定义一个整形指针 p = (int *)0x0019FF3C;//将常量0x0019FF3C强制转化为整形地址,用p指向它 *p = 1234;//向该地址写入数据 printf("%d\n",*(int *)0x0019FF3C);//输出0x0019FF3C地址的数据 return 0; } --------------------------------------- #include "stdio.h" int main() { *(int *)0x0019FF3C = 1234;//将0x0019FF3C 强制转化为整形地址(int *)0x0019FF3C,再将1234写入到该地址指向的内容 printf("%d\n",*(int *)0x0019FF3C);//输出该地址的内容 return 0; }
486:指80486处理器:
八十年代末九十年代初,80486处理器面市,它集成了120万个晶体管,时钟频率由25MHz逐步提升到50MHz 。并在X86系列中首次使用了 RISC(精简指令集)技术,可以在一个时钟周期内执行一条指令。它还采用了突发总线传送方式,大大提高了与内存的数据交换速度,由于这些改进,80486的性能比带有80387协处理器的80386提高了4倍。早期的486分为有协处理器的486DX和无协处理器的486SX两种,其价格也相差许多。
第二节
做了一处小改动
for (i = 0xa0000; i <= 0xaffff; i++) {
write_mem8(i, i & 0x0f);
}
i为地址,与00001111(2)进行与运算,则变成仅保留后4位了,所以色号会每16个像素重复一次,形成色条。
第三、四、五节
主要涉及指针
*(p+i)可以写成p[i]这种形式,p[i]=i[p]
第六节
色号设定
Red/紅色/Adobe/#ff0000/#f00十六进制颜色代码表,图表,调色板,绘图&油漆 (encycolorpedia.cn)
//bootpack.c
void set_palette(int start, int end, unsigned char *rgb)
{
int i, eflags;
eflags = io_load_eflags(); /* 妱傝崬傒嫋壜僼儔僌偺抣傪婰榐偡傞 */
io_cli(); /* 将终端标志置为0,与之对应sti是置为1 */
io_out8(0x03c8, start);
for (i = start; i <= end; i++) { /*将想要设定的调色板号码写入0x03c8*/
io_out8(0x03c9, rgb[0] / 4);
io_out8(0x03c9, rgb[1] / 4);
io_out8(0x03c9, rgb[2] / 4);
rgb += 3;
}
io_store_eflags(eflags); /* 32位寄存器 */
return;
}
; naskfunc
; TAB=4
[FORMAT "WCOFF"] ; 僆僽僕僃僋僩僼傽僀儖傪嶌傞儌乕僪
[INSTRSET "i486p"] ; 486偺柦椷傑偱巊偄偨偄偲偄偆婰弎
[BITS 32] ; 32價僢僩儌乕僪梡偺婡夿岅傪嶌傜偣傞
[FILE "naskfunc.nas"] ; 僜乕僗僼傽僀儖柤忣曬
GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt
GLOBAL _io_in8, _io_in16, _io_in32
GLOBAL _io_out8, _io_out16, _io_out32
GLOBAL _io_load_eflags, _io_store_eflags
[SECTION .text]
_io_hlt: ; void io_hlt(void);
HLT
RET
_io_cli: ; void io_cli(void);
CLI
RET
_io_sti: ; void io_sti(void);
STI
RET
_io_stihlt: ; void io_stihlt(void);
STI
HLT
RET
_io_in8: ; int io_in8(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AL,DX
RET
_io_in16: ; int io_in16(int port);
MOV EDX,[ESP+4] ; port
MOV EAX,0
IN AX,DX
RET
_io_in32: ; int io_in32(int port);
MOV EDX,[ESP+4] ; port
IN EAX,DX
RET
_io_out8: ; void io_out8(int port, int data);
MOV EDX,[ESP+4] ; port
MOV AL,[ESP+8] ; data
OUT DX,AL
RET
_io_out16: ; void io_out16(int port, int data);
MOV EDX,[ESP+4] ; port
MOV EAX,[ESP+8] ; data
OUT DX,AX
RET
_io_out32: ; void io_out32(int port, int data);
MOV EDX,[ESP+4] ; port
MOV EAX,[ESP+8] ; data
OUT DX,EAX
RET
_io_load_eflags: ; int io_load_eflags(void);
PUSHFD ; PUSH EFLAGS ,push flags double-word
POP EAX ; 这两条命令=MOV EAX,EFLAGS
RET
_io_store_eflags: ; void io_store_eflags(int eflags);
MOV EAX,[ESP+4]
PUSH EAX
POPFD ; POP EFLAGS 偲偄偆堄枴
RET
第七节
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{//参数意义:地址,屏幕的宽的像素,颜色,x轴开始,y轴开始,x轴结束,y轴结束
int x, y;
for (y = y0; y <= y1; y++) {
for (x = x0; x <= x1; x++)
vram[y * xsize + x] = c;
}
return;
}
第八节
画了个任务条,但是很丑
VRAM占用了显卡的0xa0000-0xaffff共64kb
欢迎一起学习和讨论
欢迎关注个人其他账号:
B站账号:哔哩哔哩 无名-易
Gitee账号:gitee账号
GitHub账号:GitHub