首页 > 代码库 > 30天自制操作系统(第四天)
30天自制操作系统(第四天)
8086- 80286- 80386- 80486- Pentium- Pentium Pro- Pentium 1- Pentium 2- Pentium 3 到80286都是16位CPU,其他是32位CPU
p=(char *)i; *p=i&0x0f;
改写成汇编语言就是: MOV ECX,i MOV BYTE [ECX],(i&0x0f) 具体件书72到74页,从汇编角度看,有助于更好的理解C语言的指针
p[i]与*(p+i)的意思完全相同,不是说改变一下写法,地址变量就变成数组了,不能被那些 劣质的教科书骗了,加法具有交换律,所以*(p+i)==*(i+p),因此p[i]与i[p]是等价的,比 说a[2]与2[a]是等价的
RGB调色板各种颜色及其对应的代码,书76页
cpu的管脚不仅与内存相连,还与设备相连
调色板的访问步骤(重点内容) 1.首先将一连串的访问中屏蔽中断 2,将想要设定的调色板号码写入0x03c8,紧接着,按照R,G,B的顺序写入0x03c9.如果还想继续 设定下一调色板,则省略调色板号码,在按照RGB的顺序写入0x03c9就行了 3.如果想要读出当前调色板状态,首先将调色板的号码写入0x03c7,在从0x03c9读取3次,读出的顺序 就是R,G,B.如果继续读出下一个调色板,同样也是省略调色板号码的设定,按RGB顺序读出
中断标志,只能读入eflags寄存器的第9位,进位标志是第0位
只能用pushfd,popfd指令来读写eflags
下面是第四天代码
;hello-os;TAB=4CYLS EQU 10 ORG 0X7C00 ;指明程序的装载地址 ;以下这段是标准FAT12格式软盘专用代码 JMP entry DB 0x90 DB "HARIBOTE" ;启动扇区的名称可以使任意的字符串 DW 512 ;每个扇区的大小(必须为512字节) DB 1 ;簇的大小(必须为1个扇区) DW 1 ;FAT的起始位置(一般从第一个扇区开始) DB 2 ;FAT的个数(必须为2) DW 224 ;根目录的大小(一般设置为224) DW 2880 ;该磁盘的大小(必须是2880扇区) DB 0xf0 ;磁盘的种类(必须是0xf0) DW 9 ;FAT的长度(必须是9扇区) DW 18 ;1个磁道有几个扇区(必须是18) DW 2 ;磁头数(必须是2) DD 0 ;不试用分区(必须是0) DD 2880 ;重写一次磁盘大小 DB 0,0,0x29 ;固定 DD 0xffffffff ;(可能是)卷码标号 DB "HARIBOTEOS " ;磁盘的名称(11字节) DB "FAT12 " ;磁盘格式的名称(8字节) RESB 18 ;先空出18字节;程序核心entry: MOV AX,0 ;初始化寄存器 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV AX,0x0820 MOV ES,AX MOV CH,0 ;柱面0 MOV DH,0 ;磁头0 MOV CL,2 ;扇区2readloop: MOV SI,0 ;记录失败次数的寄存器retry: MOV AH,0x02 ;AH=0x02 : 读盘 MOV AL,1 ;一个扇区 MOV BX,0 MOV DL,0x00 ;A驱动器 INT 0x13 ;调用磁盘BIOS JNC next ;没出错的话就跳转到next ADD SI,1 CMP SI,5 JAE error ;SI>=5跳转到error MOV AH,0x00 MOV DL,0x00 ;A驱动器 INT 0x13 ;重置驱动器 JMP retrynext: MOV AX,ES ;把内存地址后移0x200 ADD AX,0x0020 MOV ES,AX ;因为没有ADD ES,0x200指令 ADD CL,1 ;往CL里面加1 CMP CL,18 JBE readloop ;如果CL<=18,跳转至readloop MOV CL,1 ADD DH,1 CMP DH,2 JB readloop ;如果DH<=2,跳转到readloop MOV DH,0 ADD CH,1 CMP CH,CYLS JB readloop ;如果CH<CYLS,则跳转到readloop MOV [0x0ff0],CH JMP 0xc200 error: MOV SI,msgputloop: MOV AL,[SI] ADD SI,1 ;给SI加1 CMP AL,0 JE fin MOV AH,0x0e ;显示一个文字 MOV BX,15 ;指定字符颜色 INT 0x10 ;调用显卡BIOS JMP putloopfin: HLT ;让CPU停止循环,等待指令 JMP fin ;无限循环msg: DB 0X0a,0X0a ;换行两次 DB "load error" DB 0x0a DB 0 RESB 0x7dfe-$ ;填写0x00,直到0x001fe DB 0x55, 0xaa
1 ;naskfunc 2 ;TAB=4 3 4 [FORMAT "WCOFF"] ;制作目标文件的模式 5 [INSTRSET "i486p"] ;告诉nsk这个指令是i486 6 [BITS 32] ;制作32位模式用的机械语言 7 8 ;制作目标文件的信息 9 [FILE "naskfunc.nas"] ;源文件名信息10 GLOBAL _io_hlt, _io_cli, _io_sti, _io_stihlt11 GLOBAL _io_in8, _io_in16, _io_in3212 GLOBAL _io_out8, _io_out16, _io_out3213 GLOBAL _io_load_eflags, _io_store_eflags14 ;程序中包含的函数名15 16 ;以下是实际函数17 18 [SECTION .text] ;目标文件中写了这些之后在写程序19 _io_hlt: ; void io_hlt(void);20 HLT21 RET22 23 _io_cli: ; void io_cli(void);24 CLI25 RET26 27 _io_sti: ; void io_sti(void);28 STI29 RET30 31 _io_stihlt: ; void io_stihlt(void);32 STI33 HLT34 RET35 36 _io_in8: ; int io_in8(int port);37 MOV EDX,[ESP+4] ; port38 MOV EAX,039 IN AL,DX40 RET41 42 _io_in16: ; int io_in16(int port);43 MOV EDX,[ESP+4] ; port44 MOV EAX,045 IN AX,DX46 RET47 48 _io_in32: ; int io_in32(int port);49 MOV EDX,[ESP+4] ; port50 IN EAX,DX51 RET52 53 _io_out8: ; void io_out8(int port, int data);54 MOV EDX,[ESP+4] ; port55 MOV AL,[ESP+8] ; data56 OUT DX,AL57 RET58 59 _io_out16: ; void io_out16(int port, int data);60 MOV EDX,[ESP+4] ; port61 MOV EAX,[ESP+8] ; data62 OUT DX,AX63 RET64 65 _io_out32: ; void io_out32(int port, int data);66 MOV EDX,[ESP+4] ; port67 MOV EAX,[ESP+8] ; data68 OUT DX,EAX69 RET70 71 _io_load_eflags: ; int io_load_eflags(void);72 PUSHFD ; PUSH EFLAGS 73 POP EAX74 RET75 76 _io_store_eflags: ; void io_store_eflags(int eflags);77 MOV EAX,[ESP+4]78 PUSH EAX79 POPFD ; POP EFLAGS 80 RET
1 /*告诉C编译器,有一个函数在别的文件里面*/ 2 void io_hlt(void); 3 void io_cli(void); 4 void io_out8(int port, int data); 5 int io_load_eflags(void); 6 void io_store_eflags(int eflags); 7 8 9 //就算是写在同一个文件里面,如果想在定义前使用,还是必须事先申明一下 10 void init_palette(void); 11 void set_palette(int start, int end, unsigned char *rgb); 12 void boxfill8(unsigned char *vram,int xsize,unsigned char c,int x0,int y0,int x1,int y1); 13 14 #define COL8_000000 0 15 #define COL8_FF0000 1 16 #define COL8_00FF00 2 17 #define COL8_FFFF00 3 18 #define COL8_0000FF 4 19 #define COL8_FF00FF 5 20 #define COL8_00FFFF 6 21 #define COL8_FFFFFF 7 22 #define COL8_C6C6C6 8 23 #define COL8_840000 9 24 #define COL8_008400 10 25 #define COL8_848400 11 26 #define COL8_000084 12 27 #define COL8_840084 13 28 #define COL8_008484 14 29 #define COL8_848484 15 30 31 void HariMain(void) 32 { 33 //int i; /*变量申明*/ 34 char *vram; /*这是地址调用*/ 35 int xsize,ysize; 36 37 init_palette();/*设定调色板*/ 38 vram=(char *) 0xa0000; /*给地址变量赋初值*/ 39 xsize=320; 40 ysize=200; 41 42 boxfill8(vram, xsize, COL8_008484, 0, 0, xsize - 1, ysize - 29); 43 boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 28, xsize - 1, ysize - 28); 44 boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize - 27, xsize - 1, ysize - 27); 45 boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize - 26, xsize - 1, ysize - 1); 46 47 boxfill8(vram, xsize, COL8_FFFFFF, 3, ysize - 24, 59, ysize - 24); 48 boxfill8(vram, xsize, COL8_FFFFFF, 2, ysize - 24, 2, ysize - 4); 49 boxfill8(vram, xsize, COL8_848484, 3, ysize - 4, 59, ysize - 4); 50 boxfill8(vram, xsize, COL8_848484, 59, ysize - 23, 59, ysize - 5); 51 boxfill8(vram, xsize, COL8_000000, 2, ysize - 3, 59, ysize - 3); 52 boxfill8(vram, xsize, COL8_000000, 60, ysize - 24, 60, ysize - 3); 53 54 boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 24, xsize - 4, ysize - 24); 55 boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 23, xsize - 47, ysize - 4); 56 boxfill8(vram, xsize, COL8_FFFFFF, xsize - 47, ysize - 3, xsize - 4, ysize - 3); 57 boxfill8(vram, xsize, COL8_FFFFFF, xsize - 3, ysize - 24, xsize - 3, ysize - 3); 58 59 for(;;){ 60 io_hlt(); 61 /*这里想写上HLT,但C语言中不用HLT!*/ 62 } 63 } 64 65 void init_palette(void) 66 { 67 static unsigned char table_rgb[16*3]={ 68 0x00,0x00,0x00, //0.黑色 69 0xff,0x00,0x00, //1.亮红 70 0x00,0xff,0x00, //2.亮绿 71 0xff,0xff,0x00, //3.亮黄 72 0x00,0x00,0xff, //4.亮蓝 73 0xff,0x00,0xff, //5.亮紫 74 0x00,0xff,0xff, //6.浅亮蓝 75 0xff,0xff,0xff, //7.白 76 0xc6,0xc6,0xc6, //8.亮灰 77 0x84,0x00,0x00, //9.暗红 78 0x00,0x84,0x00, //10.暗绿 79 0x84,0x84,0x00, //11.暗黄 80 0x00,0x00,0x84, //12.暗青 81 0x84,0x00,0x84, //13.暗紫 82 0x00,0x84,0x84, //14.浅暗蓝 83 0x84,0x84,0x84 //15.暗灰 84 }; 85 set_palette(0,15,table_rgb); 86 return; 87 /*C语言中,static char语句只能用于数据,相当于汇编中的DB*/ 88 } 89 90 void set_palette(int start,int end,unsigned char *rgb) 91 { 92 int i,eflags; 93 eflags=io_load_eflags(); //记录中断许可标志的值 94 io_cli(); //将中断标志置为0,静止中断 95 io_out8(0x03c8,start); //调色板号写入0x03c8 96 for(i=start;i<=end;i++) 97 { 98 io_out8(0x03c9,rgb[0]/4); 99 io_out8(0x03c9,rgb[1]/4);100 io_out8(0x03c9,rgb[2]/4);101 rgb+=3;102 }103 io_store_eflags(eflags); /*复原中断许可标志*/104 return;105 }106 107 void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1) //给对应地址填色,循环画出对应的矩形框108 {109 int x, y;110 for (y = y0; y <= y1; y++) {111 for (x = x0; x <= x1; x++)112 vram[y * xsize + x] = c;113 }114 return;115 }
30天自制操作系统(第四天)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。