9.完善内核-实现自己的打印函数

经过前面 8 个博客,已经把执行内核之前的准备工作完成了,接下来跳转到内核执行。

本次的打印函数就是控制显卡来完成的,就像之前 MBR 读硬盘,加载loader、loader.S 读硬盘加载内核到内存一样,控制显卡就是控制显卡中相关的寄存器。

对于显卡中寄存器的控制,涉及到端口,还是直接使用汇编来实现。

步骤

  1. 备份寄存器现场
  2. 获取光标位置
  3. 获取待打印字符
  4. 判断字符是否为控制字符,回车、换行、退格。进入相应的处理流程
  5. 判断是否需要滚屏
  6. 更新光标位置
  7. 恢复寄存器现场,退出。

直接上代码,在注释中解释:
print.S

TI_GDT equ  0
RPL0  equ   0
SELECTOR_VIDEO equ (0x0003<<3) + TI_GDT + RPL0	;显存段选择子

[bits 32]
section .text
;------------------------   put_char   -----------------------------
;功能描述:把栈中的1个字符写入光标所在处
;-------------------------------------------------------------------   
global put_char		;global声明一下,外部文件可见,因为在C语言中要调用
put_char:
   pushad	   ;备份32位寄存器环境
   ;需要保证gs中为正确的视频段选择子,为保险起见,每次打印时都为gs赋值
   mov ax, SELECTOR_VIDEO	       ; 不能直接把立即数送入段寄存器
   mov gs, ax

;;;;;;;;;  获取当前光标位置 ;;;;;;;;;
   ;先获得高8位
   mov dx, 0x03d4  ;索引寄存器
   mov al, 0x0e	   ;用于提供光标位置的高8位
   out dx, al
   mov dx, 0x03d5  ;通过读写数据端口0x3d5来获得或设置光标位置 
   in al, dx	   ;得到了光标位置的高8位
   mov ah, al

   ;再获取低8位
   mov dx, 0x03d4
   mov al, 0x0f
   out dx, al
   mov dx, 0x03d5 
   in al, dx		;至此,ax 中存着光标位置

   ;将光标存入bx
   mov bx, ax	  
   ;下面这行是在栈中获取待打印的字符
   mov ecx, [esp + 36]	      ;pushad压入4×8=32字节,加上主调函数的返回地址4字节,故esp+36字节
   cmp cl, 0xd				  ;回车CR是0x0d,换行LF是0x0a
   jz .is_carriage_return
   cmp cl, 0xa
   jz .is_line_feed

   cmp cl, 0x8				  ;BS(backspace)的asc码是8
   jz .is_backspace
   jmp .put_other	   
;;;;;;;;;;;;;;;;;;

 .is_backspace:		      
;;;;;;;;;;;;       backspace的一点说明	     ;;;;;;;;;;
; 当为backspace时,本质上只要将光标移向前一个显存位置即可.后面再输入的字符自然会覆盖此处的字符
; 但有可能在键入backspace后并不再键入新的字符,这时在光标已经向前移动到待删除的字符位置,但字符还在原处,
; 这就显得好怪异,所以此处添加了空格或空字符0
   dec bx
   shl bx,1
   mov byte [gs:bx], 0x20		  ;将待删除的字节补为0或空格皆可
   inc bx
   mov byte [gs:bx], 0x07
   shr bx,1
   jmp .set_cursor
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 .put_other:
   shl bx, 1				  ; 光标位
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值