qq:992591601 欢迎交流
2016.04.20
首先,assemblyFunc.nas里面新添加内容:
; naskfunc ; TAB=4 ; author: 无 名 ; date: 2016.06.04 ; description: assembly functions [FORMAT "WCOFF"] ; 目标文件制作模式 [INSTRSET "i486p"] ; 这个程序是486 [BITS 32] ; 制作32位模式用的机械语言 [FILE "assemblyFunc.nas"] ; 源文件名 GLOBAL _io_hlt,_write_mem8 [SECTION .text] _io_hlt: ; void io_hlt(void); HLT RET _write_mem8: ; void write_mem8(int addr,int data) mov ecx,[esp + 4] ; [esp + 4]中存放的是地址,将其读入ecx mov al,[esp + 8] ; [esp + 8]中存放的是数据,将其读入al mov [ecx],al ret
添加一个write_mem8的函数,用来向内存写入。
[INSTRSET "i486p"]这句表明是486模式。
c_main.c :
void io_hlt(void); void write_mem8(int addr, int data); void HariMain(void) { int i; for (i = 0xa0000; i <= 0xaffff; i++) { write_mem8(i, i & 0x0f); } for (;;) { io_hlt(); } }
于是,画面会显示一片白色。因为第15种颜色就是纯白。
若改成
for(i = 0xa0000; i <= 0xaffff; i++){
write_mem8( i , i & 0x0f);
}
会呈现条纹图案,因为低4位保留原样,而高4位全部变为0。
特定位变为1 -------- OR
特定位变为0 -------- AND
特定位反转 -------- XOR(与1相同为0,否则为1)
已知目前画面模式为320 * 200的8位颜色模式,色号使用8位(2进制), 0 - 255。
所以做出一个调色板一切会方便很多。
8位彩色模式,即是程序员随意指定0~255的数字所对应的颜色的。这种方式叫做调色板。
为了使用INOUT指令以及读取、保存、复原sti,cli,flags,而写的汇编函数
_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 POP EAX RET _io_store_eflags: ; void io_store_eflags(int eflags); MOV EAX,[ESP+4] PUSH EAX POPFD ; POP EFLAGS RET
vga相关
void io_hlt(void); void io_cli(void); void io_out8(int port, int data); int io_load_eflags(void); void io_store_eflags(int eflags); void init_palette(void); void set_palette(int start, int end, unsigned char *rgb); void draw_box(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1); #define COL8_000000 0 #define COL8_FF0000 1 #define COL8_00FF00 2 #define COL8_FFFF00 3 #define COL8_0000FF 4 #define COL8_FF00FF 5 #define COL8_00FFFF 6 #define COL8_FFFFFF 7 #define COL8_C6C6C6 8 #define COL8_840000 9 #define COL8_008400 10 #define COL8_848400 11 #define COL8_000084 12 #define COL8_840084 13 #define COL8_008484 14 #define COL8_848484 15 void HariMain(void) { char *vram; int xsize, ysize; init_palette(); vram = (char *) 0xa0000; xsize = 320; ysize = 200; draw_box(vram,xsize,COL8_FFFF00,40,40,50,50); draw_box(vram,xsize,COL8_FFFFFF,60,60,70,70); draw_box(vram,xsize,COL8_FF0000,80,80,90,90); draw_box(vram,xsize,COL8_00FF00,100,100,110,110); draw_box(vram,xsize,COL8_0000FF,120,100,130,110); draw_box(vram,xsize,COL8_FF00FF,140,100,150,110); draw_box(vram,xsize,COL8_00FFFF,160,100,170,110); draw_box(vram,xsize,COL8_C6C6C6,100,120,110,130); draw_box(vram,xsize,COL8_840000,120,120,130,130); draw_box(vram,xsize,COL8_008400,140,120,150,130); draw_box(vram,xsize,COL8_848400,160,120,170,130); draw_box(vram,xsize,COL8_000084,180,140,190,150); draw_box(vram,xsize,COL8_840084,200,160,210,170); draw_box(vram,xsize,COL8_008484,220,160,170,170); draw_box(vram,xsize,COL8_848484,240,140,170,150); for (;;) { io_hlt(); } } void init_palette(void) { static unsigned char table_rgb[16 * 3] = { 0x00, 0x00, 0x00, /* 0:黑 */ 0xff, 0x00, 0x00, /* 1:亮红 */ 0x00, 0xff, 0x00, /* 2:亮绿 */ 0xff, 0xff, 0x00, /* 3:亮黄 */ 0x00, 0x00, 0xff, /* 4:亮蓝 */ 0xff, 0x00, 0xff, /* 5:亮紫 */ 0x00, 0xff, 0xff, /* 6:浅亮蓝 */ 0xff, 0xff, 0xff, /* 7:白 */ 0xc6, 0xc6, 0xc6, /* 8:亮灰 */ 0x84, 0x00, 0x00, /* 9:暗红 */ 0x00, 0x84, 0x00, /* 10:暗绿 */ 0x84, 0x84, 0x00, /* 11:暗黄 */ 0x00, 0x00, 0x84, /* 12:暗青 */ 0x84, 0x00, 0x84, /* 13:暗紫 */ 0x00, 0x84, 0x84, /* 14:浅暗蓝 */ 0x84, 0x84, 0x84 /* 15:暗灰 */ }; set_palette(0, 15, table_rgb); return; } void set_palette(int start, int end, unsigned char *rgb) { int i, eflags; eflags = io_load_eflags(); /* 记录中断许可标志的值 */ io_cli(); /* 将中断许可标志 */ io_out8(0x03c8, start); for (i = start; i <= end; i++) { io_out8(0x03c9, rgb[0] / 4); io_out8(0x03c9, rgb[1] / 4); io_out8(0x03c9, rgb[2] / 4); rgb += 3; } io_store_eflags(eflags); /* 复原中断许可标志 */ return; } void draw_box(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; }