发布于 

30天自制操作系统(20)

DAY20_API

1.程序整理

目标:实现由应用程序对操作系统功能的调用(即API,也叫系统调用)。

2.显示单个字符的API(1)

目标:显示单个字符的API。

  • 首先我们做一个测试用的应用程序,将要显示的字符编码存入AL寄存器,然后调用操作系
    统的函数,字符就显示出来了。
    [BITS 32] 
    MOV AL,'A'
    CALL (cons_putchar的地址)
    fin:
    HLT
    JMP fin

bootpack.map文件
这是一个文本文件,用文本编辑器打开即可,其中应该可以找到这样一行:

0x00000BE3 : _asm_cons_putchar

这就是_asm_cons_putchar的地址了,因此,我们将地址填在应用程序中.

[BITS 32] 
MOV AL,'A'
CALL 0xbe3
fin:
HLT
JMP fin

3.显示单个字符的API(2)

  • 应用程序对API执行CALL的时候,千万不能忘记加上段号。

4.结束应用程序

  • C语言中没有用来执行far-CALL的命令,我们只好来创建一个farcall函数
    _farcall: ; void farcall(int eip, int cs); 
    CALL FAR [ESP+4] ; eip, cs
    RET

5.不随操作系统版本而改变的 API

6.为应用程序自由命名

  • 目标:让系统支持其他应用程序名
    void cons_runcmd(char *cmdline, struct CONSOLE *cons, int *fat, unsigned int memtotal) 
    {
    if (strcmp(cmdline, "mem") == 0) {
    cmd_mem(cons, memtotal);
    } else if (strcmp(cmdline, "cls") == 0) {
    cmd_cls(cons);
    } else if (strcmp(cmdline, "dir") == 0) {
    cmd_dir(cons);
    } else if (strncmp(cmdline, "type ", 5) == 0) {
    cmd_type(cons, fat, cmdline);
    } else if (cmdline[0] != 0) { /*从此开始*/
    if (cmd_app(cons, fat, cmdline) == 0) {
    /*不是命令,不是应用程序,也不是空行*/
    putfonts8_asc_sht(cons->sht, 8, cons->cur_y, COL8_FFFFFF, COL8_000000, "Bad command.",
    12);
    cons_newline(cons);
    cons_newline(cons);
    }
    } /*到此结束 */
    return;
    }

7.当心寄存器

  • 命名只显示一个h
  • 给_asm_cons_putchar添上2行代码,就是PUSHAD和POPAD。

8.用API显示字符

  • 从实际的应用程序开发角度来说,能显示字符串的API远比只能显示单个字符的API要来的方便,因为一次显示一串字符的情况比一次只显示一个字符的情况多得多。
  • 一般有两种方式:
    • 种是显示一串字符,遇到字符编码0则结束;
    • 先指定好要显示的字符串的长度再显示。
功能号 1……显示单个字符(AL = 字符编码)
功能号 2……显示字符串 0(EBX = 字符串地址)
功能号 3……显示字符串 1(EBX = 字符串地址,ECX = 字符串长度)
  • 将_asm_cons_putchar改写成一个新的函数。
    _asm_hrb_api:
    STI
    PUSHAD;
    PUSHAD;
    CALL _hrb_api
    ADD ESP,32
    POPAD
    IRETD