30天自制操作系统
上QQ阅读APP看书,第一时间看更新

3 整理头文件(harib03c)

Makefile变短了,真让人高兴。我们继续把源文件也整理一下。现在的文件大小如下。

graphic.c ….............. 187行

dsctbl.c …................ 67行

bootpack.c …............ 81行

合计 …...........….... 335行

这比分割前的280行多了不少。主要原因在于各个源文件都要重复声明“vold io_out8(int port, int data); ”等,虽然说这也是迫不得已,但还是不甘心。所以,我们在这儿再下点工夫。

■■■■■

首先将重复部分全部去掉,把他们归纳起来,放到名为bootpack.h的文件里。虽然扩展名变了,但它也是C语言的文件。已经有一个文件名叫bootpack.c了,我们根据一般的做法,将文件命名为bootpack.h。因为是第一次接触到.h文件,所以我们截取bootpack.h内容靠前的一段放在下面。

bootpack.h的内容

/* asmhead.nas */
struct BOOTINFO { /* 0x0ff0-0x0fff */
    char cyls; /* 启动区读硬盘读到何处为止 */
    char leds; /* 启动时键盘LED的状态 */
    char vmode; /* 显卡模式为多少位彩色 */
    char reserve;
    short scrnx, scrny; /* 画面分辨率 */
    char *vram;
};
#define ADR_BOOTINFO     0x00000ff0

/* naskfunc.nas */
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 load_gdtr(int limit, int addr);
void load_idtr(int limit, int addr);

/* graphic.c */
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 init_screen8(char *vram, int x, int y);
   (以下略)

这个文件里不仅仅罗列出了函数的定义,还在注释中写明了函数的定义在哪一个源文件里。想要看一看或者修改函数定义时,只要看一下文件bootpack.h就能知道该函数定义本身在哪个源文件里。这就像目录一样,很方便。

在编译graphic.c的时候,我们要让编译器去读这个头文件,做法是在graphic.c的前面加上如下一行:

#include "bootpack.h"

编译器见到了这一行,就将该行替换成所指定文件的内容,然后进行编译。所以,写在“bootpack.h”里的所有内容,也都间接地写到了“graphic.c”中。同样道理,在“dsctbl.c”和“bootpack.c”的前面也都加上一行“#include "bootpack.h"”。

■■■■■

像这样,仅由函数声明和#define等组成的文件,我们称之为头文件。头文件英文为header,顾名思义,是指放在程序头部的文件。为什么要放在头部呢?因为像“void io_out8(int port, int data); ”这种声明必须在一开始就让编译器知道。

前面曾经提到,要使用spintf函数,必须在程序的前面写上#include <stdio.h>语句。这正是因为stdio.h中含有对sprintf函数的声明。虽然括住文件名的记号有引号和尖括号的区别,但那也只是文件所处位置的不同而已。双引号("")表示该头文件与源文件位于同一个文件夹里,而尖括号(< >)则表示该头文件位于编译器所提供的文件夹里。

这次用了很多#define语句,把用到的地址都只写在了bootpack.h文件里。之所以这么做是因为,如果以后想要变更地址的话,只修改bootpack.h一个文件就行了。

好了,我们运行一下每次必做的“make run”确认一下。挺好挺好,运行结果没有问题。现在再来确认一下源文件的长度。

bootpack.h ….............. 69行

graphic.c …............. 156行

dsctbl.c …................. 51行

bootpack.c …............. 25行

合计 ......................... 301行

整体共缩短了34行分割前是280行,这样算来结果还增加了21行,不过因为我们进行了分割,所以无法避免这种情况。而我们分割的目的也不是为了缩短源文件,所以总的来说还是比较满意的。(可在6.1节确认分割的目的),真是太好了。