从头写一个操作系统 14 (在屏幕上打印点什么)

如果跟着我学到现在,一定知道到哪里去下载代码,算了,地址在这https://github.com/cfenollosa/os-tutorial/tree/master/15-video-ports,这个地址里有这节课要用到的代码,如果之前你只是看看就算了,这节课就是不上手就再也跟不上的关键节点。代码中有一点点问题,Makefile中在qemu 调用-s时加一个-S(比如这样 -sS),这样gdb才能够真正控制qemu的运行。

看到代码了吗?如果还没打开代码,本课程将不再欢迎你。

drive文件夹中有两个c程序,用到了Inline Assembly的写法,这是一个难点,这段代码这么写就显得更加难理解。
原本的Inline Assembly的用法是这样:

int a=10, b;
asm ("movl %1, %%eax; 
      movl %%eax, %0;"
     :"=r"(b)        /* 输出 */
     :"r"(a)         /* 输入 */
     :"%eax"         /* 用到的寄存器 */
     );

我们的代码是这样

    __asm__("in %%dx, %%al"
 : "=a" (result)
 : "d" (port));

"in %%dx, %%al"就是汇编指令
"=a" (result) 是指将eax寄存器的值写入c语言中的变量result中。
"d" (port)) 是指将port变量的值写到edx中。
绕不绕?感觉绕就正常了,因为你不知道in %%dx, %%al是在干什么,让我们看看kernel/kernel.c中如何调用这段代码的。

 port_byte_out(0x3d4, 14); /* 14是请求高位字节,0x3d4是一个地址,用于与显卡交互 */
    /* 索取的数据将出现在 (0x3d5)中 */
    int position = port_byte_in(0x3d5);
    position = position << 8; /* high byte */

    port_byte_out(0x3d4, 15); /* 请求低位字节 */
    position += port_byte_in(0x3d5);

其实它是在请求显卡告诉咱们,现在光标在什么位置,光标的位置是一个16位的数据,分两个字节提取,提取流程是:
1.在0x3d4位置写入14,光标位置高字节信息出现在0x3d5中
2.在0x3d4位置写入15,光标位置低字节信息结果出现在0x3d5中。
由此,实现了一个显示数据的接口,以后再要打印什么ASCII码就方便多了。

你可能感兴趣的:(从头写一个操作系统 14 (在屏幕上打印点什么))