自制操作系统日记(6):静态桌面初步
创始人
2024-01-22 13:25:16
0

代码仓库地址:https://github.com/freedom-xiao007/operating-system

简介

在上篇中我们成功的加载跳转执行了C语言的代码,本篇中将跟随书籍,初步展示了一个系统页面的初步界面,看到桌面那刻还是有点意思的

最终结果展示

不多啰嗦,这里先直接展示结果,最终的运行界面如下:

在这里插入图片描述

可以看到有点模样了,令人激动啊。当最终到这一步的时候,心里开心极了,哈哈

相关代码说明

本篇中的代码修改基本上是抄《30天自制操作系统》中的,但可能是nask和nasm的区别问题,我们需要单独修改的地方也不少,下面我们详细说明下需要修改的地方

setup.asm文件修改

这个文件需要添加界面相关的参数设置,我们将其插入到start的下面,如下:

start:; 画面モードを設定MOV		AL,0x13			; VGA显卡,320x200x8bitMOV		AH,0x00INT		0x10MOV		BYTE [VMODE],8	; 屏幕的模式(参考C语言的引用)MOV		WORD [SCRNX],320MOV		WORD [SCRNY],200MOV		DWORD [VRAM],0x000a0000

func.asm文件修改

这次新增了比较多的函数,但不复杂,也不多,这个文件的内容如下:

[BITS 32]                          ; 制作32位模式用的机器语言GLOBAL  _io_hlt, _io_cli, _io_sti, io_stihltGLOBAL  _io_in8,  _io_in16,  _io_in32GLOBAL  _io_out8, _io_out16, _io_out32GLOBAL  _io_load_eflags, _io_store_eflags
[SECTION .text]
_io_hlt:     ; void io_hlt(void);HLTRET
_io_cli:     ; void io_cli(void);CLIRET
_io_sti:     ; void io_sti(void);STIRET
_io_stihlt: ; void io_stihlt(void);STIHLTRET
_io_in8:     ; int io_in8(int port);MOV      EDX, [ESP+4]      ; portMOV      EAX,0IN       AL, DXRET
_io_in16:   ; int io_in16(int port);MOV      EDX, [ESP+4]      ; portMOV      EAX,0IN       AX, DXRET
_io_in32:   ; int io_in32(int port);MOV      EDX, [ESP+4]      ; portIN       EAX, DXRET
_io_out8:   ; void io_out8(int port, int data);MOV      EDX, [ESP+4]      ; portMOV      AL, [ESP+8]       ; dataOUT      DX, ALRET
_io_out16:  ; void io_out16(int port, int data);MOV      EDX, [ESP+4]      ; portMOV      EAX, [ESP+8]      ; dataOUT      DX, AXRET
_io_out32:  ; void io_out32(int port, int data);MOV      EDX, [ESP+4]      ; portMOV      EAX, [ESP+8]      ; dataOUT      DX, EAXRET
_io_load_eflags:     ; int io_load_eflags(void);PUSHFD       ; 指PUSH EFLAGSPOP      EAXRET
_io_store_eflags:   ; void io_store_eflags(int eflags);MOV      EAX, [ESP+4]PUSH EAXPOPFD ; 指POP EFLAGSRET

c入口文件修改

本次直接使用书中的C相关代码,但有几处不适配,需要我们单独进行修改

  1. 第一处是原书中的boxfill8函数,用于绘制矩形的:原书中是选循环y再循环x,但在博主运行时,总是会多出一个memset函数,导致运行失败,系统不断重启

需要将其修改下,替换为先循环x再循环y(不断地尝试后发现的,但没有搞懂为啥会这样)

  1. 第二处是调用boxfill8时的线条高度问题:原书中下发的两个矩形都是线条出度为1左右(我猜测),但在博主尝试中,小于3的高度不会显示

这里就需要修改下传入boxfill8的y0和y1的差值最小为3

经过修改后,文件的所有内容如下:

#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 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 boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);void start(void)
{init_palette(); /* 设定调色板 */char *vram; /* 变量p是BYTE [...]用的地址 */vram = (char *) 0xa0000; /* 指定地址 */int xsize = 320;int ysize = 200;boxfill8(vram, xsize, COL8_008484,  0,         0,          xsize, ysize - 29);boxfill8(vram, xsize, COL8_C6C6C6,  0,         ysize - 28, xsize, ysize - 28);boxfill8(vram, xsize, COL8_FFFFFF,  0,         ysize - 27, xsize, ysize - 27);boxfill8(vram, xsize, COL8_C6C6C6,  0,         ysize - 26, xsize, ysize -  1);//     y距离有时候需要大于3boxfill8(vram, xsize, COL8_FFFFFF,  3,         ysize - 24, 59,         ysize - 21);boxfill8(vram, xsize, COL8_FFFFFF,  2,         ysize - 24,  2,         ysize -  4);boxfill8(vram, xsize, COL8_848484,  3,         ysize -  4, 59,         ysize -  1);boxfill8(vram, xsize, COL8_848484, 59,         ysize - 23, 59,         ysize -  5);boxfill8(vram, xsize, COL8_000000,  2,         ysize -  3, 59,         ysize -  0);boxfill8(vram, xsize, COL8_000000, 60,         ysize - 24, 60,         ysize -  3);boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 24, xsize -  4, ysize - 21);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 -  0);boxfill8(vram, xsize, COL8_FFFFFF, xsize -  3, ysize - 24, xsize -  3, ysize -  3);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;/* C语言中的static char语句只能用于数据,相当于汇编中的DB指令 */
}void set_palette(int start, int end, unsigned char *rgb)
{int i, eflags;eflags = io_load_eflags();  /* 记录中断许可标志的值*/io_cli();                      /* 将中断许可标志置为0,禁止中断 */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 boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{int x, y;for (x = x0; x <= x1; x++) {for (y = y0; y <= y1; y++) {vram[y * xsize + x] = c;}}return;
}

脚本还是使用原来的,本篇中没有变化,一键运行后,出现文章开头令人激动的画面

初步感受C代码转汇编

在书中开始时介绍了不同手段实现同一个效果:给内存赋值

第一个方式是使用wirte_mem8时的编译nasm代码:使用写汇编函数的方式,根据传入的值,写到相应的内存中

void write_mem8(int addr, int data);
void start(void) {int i;for (i = 0xa0000; i < 0xaffff; i++) {write_mem8(i, i & 0x0f);}
}
ALIGN   8
?_001:  mov     eax, ebx                                ; 0018 _ 89. D8mov     dword [esp], ebx                        ; 001A _ 89. 1C 24add     ebx, 1                                  ; 001D _ 83. C3, 01and     eax, 0FH                                ; 0020 _ 83. E0, 0Fmov     dword [esp+4H], eax                     ; 0023 _ 89. 44 24, 04call    _write_mem8                             ; 0027 _ E8, 00000000(rel)cmp     ebx, 720895                             ; 002C _ 81. FB, 000AFFFFjnz     ?_001                                   ; 0032 _ 75, E4_write_mem8:     ; void write_mem8(int addr, int data);MOV      ECX, [ESP+4]      ; [ESP + 4]中存放的是地址,将其读入ECXMOV      AL, [ESP+8]       ; [ESP + 8]中存放的是数据,将其读入ALMOV      [ECX], ALRET

第二个是指针,使用char*时的编译nasm代码:突然有种回到以前学习C的感觉,想到初期使用指针时的痛苦

void start(void) {int i;char *p;for (i = 0xa0000; i < 0xaffff; i++) {p = (char *) i;*p = i & 0x0f;}/* 或者下面这样写,生成的汇编码也一样 */char *p;p = (char *) 0xa0000; /*将地址赋值进去*/for (i = 0; i <= 0xffff; i++) {p[i] = i & 0x0f;}
}
?_001:  mov     edx, eax                                ; 0018 _ 89. C2add     eax, 1                                  ; 001A _ 83. C0, 01and     edx, 0FH                                ; 001D _ 83. E2, 0Fmov     byte [eax-1H], dl                       ; 0020 _ 88. 50, FFcmp     eax, 720895                             ; 0023 _ 3D, 000AFFFFjnz     ?_001                                   ; 0028 _ 75, EE

可以看到两种不同的实现方式,对C的指针有了更深的理解,了解底层确实是有一定帮助的

总结

本文相对而言还是比较顺利的,虽然有一点坎坷,但在不断的调试中,顺利解决了

还进一步理解了C的指针

但关于书中的控制屏幕显示部分,目前还不是很通透,很需要再刷刷

相关内容

热门资讯

人生的励志箴言 关于人生的励志箴言  1.朋友是雨中伞,遮风挡雨; 朋友是雪中炭,暖心驱寒;朋友是被中棉,温暖身心;...
不悔梦归处美文 不悔梦归处美文  今天去图书馆,一下午的时间看了点刘庸的《我不是教你祚》,晚上时也实在是无聊,又不想...
十部必看韩剧历史剧   大家看韩剧喜欢看韩国的历史剧吗?下文是励志网整理的十部必看韩剧历史剧,希望能帮助到你。  十部必...
青春奋斗带字励志图片   伟人之所以伟大,是因为他与别人共处逆境时,别人失去了信心,他却下决心实现自己的目标。下面是由yj...
古人关于描写云的励志诗句集锦 天空中又出现许多千变万化的云彩,时而像羽毛,轻轻地漂泊在空中;时而像羊群,缓缓地移动;时而像大海,翻...
校园励志电影 应届毕业生励志网分享15部校园励志电影:  1、律政俏佳人1、2(Legally Blonde)……...
生产管理励志口号 生产管理励志口号大全  1. 异常改善改善再改善,浪費减少减少再减少  2. 小问题,要重视,老毛病...
tvb励志电视剧2017   2017tvb新片巡礼剧有哪些?2017年tvb依然有好多好看的电视剧准备开播?下面我们一起来看...
励志江苏大龄考生陈洪涛 励志江苏大龄考生陈洪涛  参加16个专业自考  他还拥有多张资格证书  陈洪涛高中毕业后就去了扬州电...
青春励志女生合唱歌曲   导语:有哪些适合女孩子合唱的青春励志歌曲呢?以下是小编收集整理的青春励志女生合唱歌曲,希望大家喜...
青春励志人生小说   青春啊,难道你始终囚禁在狭小圈子里?你得撕破老年的蛊惑人心的网。今天励志网就为大家推荐一些青春励...
高考励志对联集锦   引导语:不知不觉,高考又要来到了,为了鼓励考生,下面unjs小编为大家带来关于高考励志的对联集锦...
四年级语文《徐悲鸿励志学画》... 四年级语文《徐悲鸿励志学画》教学反思  作为一名到岗不久的老师,我们的任务之一就是教学,对教学中的新...
励志歌曲集 励志歌曲之一腾格尔:大男人罗嘉良:创造晴天温兆伦:从未试过拥有Michael Learns To R...
初三班级励志誓词   导语:中考不相信“如果”,多一份勤奋,少一份后悔。在面对即将到来的高考,以下是小编整理的关于初三...
特深沉的人生感悟语句励志 特深沉的人生感悟语句【励志】  人生最重要的不是我们置身何处,而是我们将前往何处,特深沉的人生感悟语...
励志电影《土豪的情人节》推荐   土豪情人节又名土豪520。  《土豪520》是中国电影股份有限公司、江苏幸福蓝海院线有限公司、浙...
励志八字真言 励志八字真言  1、自加压力,敢于争先。  2、孜孜不倦,蒸蒸日上。  3、愚者千虑,必有一得。  ...
成功女人的励志故事 成功女人的励志故事  导语:谁说女子不如男?现在的女子可是个个都能够撑起半边天,事事靠自己。下面是小...
高三励志文章:高三,时间是赞... 高三励志文章:高三,时间是赞下来的    离2011年高考还剩下大约50天的时间了。    我们在复...