首页 > 代码库 > 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天自制操作系统(第四天)