实现putchar

1.在lib/kernel/print.S 文件中实现put_char()

2.思路

①我们前面在全局描述符表GDT中定义的第三个描述符,就是我们的显存段描述符,我们往显存段中写入内容,便会输出到屏幕上。
②如果接受到的这个字符是回车/换行/删除键,那么需要特殊处理
③如果当前整个屏幕满了,那么需要整体往上挪一行,把最后一行空出来
④默认是80*25的
⑤每次都需获取光标位置,来进行接下来的操作
⑥访问CRT controller寄存器组的的寄存器,先往端口地址为0x03d4的Address Register寄存器中写入寄存器的索引,然后再从端口地址为0x03d5的Data Register寄存器中读写数据

3.代码

TI_GDT  EQU  0
RPL0  	EQU    0 
SELECTOR_VIDEO	EQU (0x0003<<3) + TI_GDT + RPL0
 //显存段描述符

[BITS 32]
SECTION .text

;/*******put char**********/
global put_char
put_char:
	PUSHAD			;save all registers
	MOV AX, SELECTOR_VIDEO
	MOV GS, AX

	;获取当前光标的位置
	;High 8 bit
	MOV DX, 0x03d4
	MOV AL, 0x0e
	OUT DX, AL
	MOV DX, 0x03d5
	IN  AL, DX
	MOV AH, AL

	;Low 8 bit
	MOV DX, 0x03d4
	MOV AL, 0x0f
	OUT DX, AL
	MOV DX, 0x03d5
	IN  AL, DX

	MOV BX, AX		;保存当前的光标位置
	
	;获取栈中那个 字符参数
	MOV ECX, [ESP+36]

	CMP CL, 0xd
	JZ  .is_carriage_return

	CMP CL, 0xa    ;换行
	JZ  .is_line_feed

	CMP CL, 0x8    ;退格 也就是删除键
	JZ  .is_backspace
	JMP .put_other


.is_backspace://如果是删除键
	DEC BX				;cursor--
	SHL BX, 1
	MOV byte [GS:BX], 0x20		;0x20 = space
	INC BX
	MOV byte [GS:BX], 0x07
	SHR BX, 1
	JMP .set_cursor



.put_other:
	SHL BX, 1
	MOV [GS:BX], CL			;CL is Ascii
	INC BX
	MOV byte [GS:BX], 0x07          ;black background white font
	SHR BX, 1
	INC BX
	CMP BX, 2000			;line end
	JL  .set_cursor


.is_line_feed:				;\n \r
.is_carriage_return:
	MOV DX, 0
	MOV AX, BX
	MOV SI, 80
	DIV SI
	SUB BX, DX


.is_carriage_return_end:
	ADD BX, 80
	CMP BX, 2000
.is_line_feed_end:
	jl .set_cursor


 
	


.roll_screen:				;start addr 0xc00b8000  all is 2000
	CLD				;DF = 0
	MOV ECX, 960			;2000-80 = 1920 1920*2 = 3840 Bytes
					;3840/4 = 960
	MOV ESI, 0xc00b80a0		;a0 = 160 = 80*2Bytes
	MOV EDI, 0xc00b8000
	REP MOVSD

;/*******Clear End Line****/
	MOV EBX, 3840
	MOV ECX, 80
	
.cls:
	MOV word [GS:EBX], 0x0720	;black background white font
	ADD EBX, 2
	LOOP .cls
	MOV BX, 1920 			;last line
	
.set_cursor://写入新的光标位置

	;Set High 8 bit
	MOV DX, 0x03d4
	MOV AL, 0x0e
	OUT DX, AL
	MOV DX, 0x03d5
	MOV AL, BH
	OUT DX, AL

	;Set Low 8 bit
	MOV DX, 0x03d4
	MOV AL, 0x0f
	OUT DX, AL
	MOV DX, 0x03d5
	MOV AL, BL
	OUT DX, AL

.put_char_down:
	popad
	ret
上一篇:netty 处理客户端连接


下一篇:NOIP 模拟 $36\; \rm Cicada 与排序$