30天自制操作系统(19)
DAY19_应用程序
1.type命令
- 在Windows的命令行中,有一个叫做type的命令,输入“type 文件名”就会显示出文件的内容。
磁盘映像中的地址 = clustno * 512 + 0x003e00 |
- 将s[0~10]这11个字节用空格的字符编码填充,然后读取cmdline[5~]并复制到s[0~],在复制的同时,将其中的小写字母转换为大写字母。随后,当遇到句点时,则可以断定接下来的部分为扩展名,于是将复制的目标改为s[8~]。经过这样的转换,我们就得到了和磁盘内格式相同的文件名。
- “寻找文件”这一段中,我们在磁盘中寻找与所输入的文件名相符的文件。如果成功找到指
定文件,则用break跳出for循环;如果找不到,则会在x到达224或者finfo[x].name[0]为0x00时结束循环。
/* type命令*/ |
2.type命令改良
目标:实现对换行的支持。
0x09……制表符:显示空格直到 x 被 4 整除为止
0x0a……换行符:换行
0x0d……回车符:忽略我们这里所说的制表符也称为水平制表符(horizonal tab),因为对齐字符位置是在水平方向上移动。相对的,还有一种垂直制表符(vertical tab)
- 在Windows中换行的字符编码为“0x0d 0x0a”两个字节,而Linux中只有“0x0a”一个字节。
- 字符编码0x0a原本代表折行(line feed)的意思,即只是移动到下一行。
- 0x0d,也就是回车符的文字编码,代表“让打印头(或者打字机的辊筒)回到行首”的意思,因此才被称为“回车”(carriage return)。
3.对FAT的支持
- 现在的type命令,肯定可以正确显示文件开头的512个字节的内容,但是如果遇到大于512个字节的文件,中间可能就会突然显示出其他文件的内容。
- 对于文件的下一段存放在哪里,在磁盘中是有记录的,我们只要分析这个记录,就可以正确读取文件内容了。
- 它位于从0柱面、0磁头、2扇区开始的9个扇区中,在磁盘映像中相当于0x000200~0x0013ff。这个记录被称为FAT,是“file allocation table”的缩写,翻译过来叫作“文件分配表”(即记录文件在磁盘中存放位置的表)。
4.代码整理
- 窗口相关函数 → window.c
- 命令行窗口相关函数 → console.c
- 文件相关函数 → file.c
5.第一个应用程序
[BITS 32]
fin:
HLT
JMP fin
[BITS 32] |
- 像type命令一样,我们用file_loadfile将文件的内容读到内存中
- 应用程序不知道自己被读到哪个内存地址,这里暂且由ORG0来生成。因此,为了应用程序能够顺利运行,我们需要为其创建一个内存段。
- 段创建好之后,接下来只要goto到该段中的程序,程序应该就会开始运行了。要goto到其他的内存段,在汇编语言中用farjmp指令。
for (y = 0; y < 11; y++) {
s[y] = ' ';
}
s[0] = 'H';
s[1] = 'L';
s[2] = 'T';
s[8] = 'H';
s[9] = 'R';
s[10] = 'B';
for (x = 0; x < 224; ) {
if (finfo[x].name[0] == 0x00) {
break;
}
if ((finfo[x].type & 0x18) == 0) {
for (y = 0; y < 11; y++) {
if (finfo[x].name[y] != s[y]) {
goto hlt_next_file;
}
}
break; /*找到文件*/
}
hlt_next_file:
x++;
}
if (x < 224 && finfo[x].name[0] != 0x00) {
/*找到文件的情况*/
p = (char *) memman_alloc_4k(memman, finfo[x].size);
file_loadfile(finfo[x].clustno, finfo[x].size, p, fat, (char *)
(ADR_DISKIMG + 0x003e00));
set_segmdesc(gdt + 1003, finfo[x].size - 1, (int) p, AR_CODE32_ER);
farjmp(0, 1003 * 8);
memman_free_4k(memman, (int) p, finfo[x].size);
} else {
/*没有找到文件的情况*/
putfonts8_asc_sht(sheet, 8, cursor_y, COL8_FFFFFF, COL8_000000, "File
not found.", 15);
cursor_y = cons_newline(cursor_y, sheet);
}
/*到此结束*/