1.【VGA图形系统初探】

提示:可以将virtualbox虚拟机界面大小设置大一些。https://jingyan.baidu.com/article/6525d4b13b7d0fac7d2e94ef.html

1、设置背景色为白色

设置背景色为白色

前提条件:需要要将VGA显卡设置为图形模式,在boot中写,代码如下:

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;设置VGA图形格式
  mov al, 0x13
  mov ah, 0x00
  int 0x10
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;

AH=0x00;
AL=模式:(省略了一些不重要的画面模式)
0x03:16位字符模式,80x25
0x12:VGA图形模式,640x480x4位彩色模式,独特的4面存储模式
0x13:VGA图形模式,320x200x8位彩色模式,调色板模式
0x6a:扩展VGA图形模式,800x600x4位彩色模式,独特的4面存储模式(有的显卡不支持这种模式)
返回值:无
我们暂且选择0x13模式,因为8位彩色模式可以使用256种颜色,这一点看来不错。
写显卡

; 导出函数
global  write_mem8

[SECTION .text]
; ========================================================================
;                  void write_mem8(int addr, int data);
; ========================================================================
write_mem8:
    mov ecx, [esp + 4]      ; [esp + 4]中存放的是地址,将其读入ecx
    mov al, [esp + 8]       ; [esp + 8]中存放的是数据,将其读入al
    mov [ecx], al
    ret

c语言设置背景色位白色

void set_background_white(){    
    for(int i = 0xa0000; i<=0xaffff; i++){
        write_mem8(i, 15);
    }
}

2、设置背景为条纹图案

条纹背景
void set_background_stripe(){   
    for(int i = 0xa0000; i<=0xaffff; i++){
        write_mem8(i, i & 0x0f);
    }
}

c语言可以直接使用指针操作内存,不用借助于汇编!
char *p; // 用于BYTE类地址
short *p // 用于WORD类地址
int *p // 用于DWORD类地址

void set_background_stripe(){   
    char *p;
    for(int i = 0xa0000; i<=0xaffff; i++){
        p = (char *) i;
        *p = i & 0x0f;
    }
}

3、设置调色板,色号
这次使用的是320x200的8位颜色模式,色号使用8位(二进制)数,也就是只能使用0~255的数。
RGB使用6位16进制数,也就是24位(二进制)来指定颜色。
这个8位彩色模式,是由程序随意指定0~255的数字所对应的颜色的。
例如25号颜色对应#ffffff,26号颜色对应对应#123456,等,这种方式叫叫做调色板。(palette)
如果程序员不做任何设定,0号颜色就是#000000,15号颜色就是#ffffff。
c:初始化调色板

// 初始化调色板
void init_palette(){
    // 我们只设置如下16种颜色就可以了
    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);
}

// 设置调色板
void set_palette(int start, int end, unsigned char *rgb){
    int eflags = io_load_eflags();    // 记录中断许可标志的值
    io_cli();                         // 将中断许可标志置为0,禁止中断
    
    io_out8(0x03c8, start);
    for(int 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);
}

asm:依赖函数

; ========================================================================
;                  void io_out8(int port, int data);
; ========================================================================
io_out8:
    mov edx, [esp + 4]      ; port
    mov al,  [esp + 8]      ; data
    mov dx, al
    ret
    
; ========================================================================
;                  int io_load_eflags();
; ========================================================================
io_load_eflags:
    pushfd         ; 指push eflags
    pop eax        ; 函数执行完毕后,如果返回值小于等于4字节,则会将值保存在寄存器eax中
    ret

; ========================================================================
;                  void io_store_eflags(int eflags);
; ========================================================================
io_load_eflags:
    mov eax, [esp + 4]
    push eax
    popfd          ; 指pop eflags
    ret     
    
; ========================================================================
;                  void io_cli();
; ========================================================================
io_cli:
    cli
    ret 

c语言函数返回值问题https://blog.csdn.net/wanna_wsl/article/details/70550825

4、绘制矩形

画面上由320x200=64000个像素。
假设左上点的坐标是(0, 0),右下点的坐标是(319, 199),那么像素坐标(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){
    for(int y = y0; y <= y1; y++){
        for(int x = x0; x <= x1; x++){
            vram[y * xsize + x] = c;
        }
    }
}

调用

    // 绘制矩形
    char *p = (char *) 0xa0000;
    boxfill8(p, 320, COL8_FF0000,  20, 20, 120, 120);
    boxfill8(p, 320, COL8_00FF00,  70, 50, 170, 150);
    boxfill8(p, 320, COL8_0000FF, 120, 80, 220, 180);

5、绘制界面

效果
// 绘制ui
void draw_ui(){
    init_palette();
    
    char *vram = (char *) 0xa0000;
    const int xsize = 320;
    const int ysize = 200;
    
    boxfill8(vram, xsize, COL8_008484, 0,        0, xsize - 1, ysize - 29);
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-28, xsize - 1, ysize - 28);
    boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize-27, xsize - 1, ysize - 27);
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-26, xsize - 1, ysize -  1);
    
    boxfill8(vram, xsize, COL8_FFFFFF,  3, ysize-24, 59, ysize -24);
    boxfill8(vram, xsize, COL8_FFFFFF,  2, ysize-24,  2, ysize - 4);
    boxfill8(vram, xsize, COL8_848484,  3, ysize- 4, 59, ysize - 4);
    boxfill8(vram, xsize, COL8_848484, 59, ysize-23, 59, ysize - 5);
    boxfill8(vram, xsize, COL8_000000,  2, ysize- 3, 59, ysize - 3);
    boxfill8(vram, xsize, COL8_000000, 60, ysize-24, 60, ysize - 3);
    
    boxfill8(vram, xsize, COL8_848484,  xsize - 47, ysize- 24, xsize - 4, ysize - 24);
    boxfill8(vram, xsize, COL8_848484,  xsize - 47, ysize- 23, xsize -47, ysize -  4);
    boxfill8(vram, xsize, COL8_FFFFFF,  xsize - 47, ysize-  3, xsize - 4, ysize -  3);
    boxfill8(vram, xsize, COL8_FFFFFF,  xsize -  3, ysize- 24, xsize - 3, ysize -  3);
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容