80 lines
3.0 KiB
NASM
80 lines
3.0 KiB
NASM
[SECTION .text]
|
||
|
||
[BITS 32]
|
||
|
||
DEFAULT_COLOR equ 0f00h
|
||
|
||
global kprintf
|
||
;===============================================
|
||
; void kprintf(u16 disp_pos, const char *format, ...)
|
||
; 参数说明:
|
||
; disp_pos: 开始打印的位置,0为0行0列,1为0行1列,80位1行0列
|
||
; format: 需要格式化输出的字符串,默认输出的字符颜色为黑底白字
|
||
; %c: 输出下一个参数的字符信息(保证参数范围在0~127),输出完打印的位置往下移动一位
|
||
; %b: 更改之后输出的字符的背景色(保证参数范围在0~15)
|
||
; %f: 更改之后输出的字符的前景色(保证参数范围在0~15)
|
||
; %s(提高内容): 参考inc/terminal.h,传进来的是一个结构体,结构体参数足够明确不复赘述,
|
||
; 输出是独立的,输出完打印的位置不会往下移动一位,不会影响接下来%c的输出的颜色
|
||
; 其余字符:按照字符输出(保证字符里不会有%,\n等奇奇怪怪的字符,都是常见字符,%后面必会跟上述三个参数之一),输出完打印的位置往下移动一位
|
||
kprintf:
|
||
; jmp $
|
||
push ebp
|
||
mov ebp, esp
|
||
push edi
|
||
push esi
|
||
push ebx ; %ebp, %ebx, %edi, %esi, %esp are callee saved regs
|
||
mov esi, 0 ; string offset
|
||
mov edi, [ebp + 8] ; disp_pos, stack always word aligned
|
||
mov ebx, [ebp + 12] ; format base
|
||
mov edx, 4 ; offset from ebp of the first va_list
|
||
mov ecx, DEFAULT_COLOR ; color
|
||
xor eax, eax ; clear eax
|
||
.loop:
|
||
movzx eax, byte [ebx + esi] ; fetch a char into eax
|
||
inc esi ;
|
||
cmp al, 0
|
||
je .exit ; if reaches \0, then break
|
||
|
||
cmp al, '%'
|
||
jne .normal_print
|
||
movzx eax, byte [ebx + esi]
|
||
inc esi ; handle special format
|
||
cmp al, 'c'
|
||
je .fmt_c
|
||
cmp al, 'b'
|
||
je .fmt_b
|
||
cmp al, 'f'
|
||
je .fmt_f
|
||
dec esi ; fall back to normal print
|
||
movzx eax, byte [ebx + esi]
|
||
jmp .normal_print
|
||
.fmt_c:
|
||
mov eax, [ebp + edx * 4] ; fetch va into eax, here its a byte of character
|
||
inc edx ; align to 4bytes, maybe
|
||
jmp .normal_print
|
||
.fmt_b:
|
||
mov eax, [ebp + edx * 4]
|
||
inc edx
|
||
and cx, 00F00H ; clear background color(and keep foreground)
|
||
shl ax, 12
|
||
or cx, ax
|
||
jmp .loop ; not a printable option
|
||
.fmt_f:
|
||
mov eax, [ebp + edx * 4]
|
||
inc edx
|
||
and cx, 0F000H ; clear foreground color(and keep backgroung)
|
||
shl ax, 8
|
||
or cx, ax
|
||
jmp .loop ; not a printable option
|
||
.normal_print:
|
||
or ax, cx ; combine character and color
|
||
mov word[gs:edi * 2], ax; load to dest video mem, edi as the cursor
|
||
inc edi ; cursor ++
|
||
jmp .loop ; it is a while loop
|
||
.exit:
|
||
pop ebx
|
||
pop edi
|
||
pop esi
|
||
leave
|
||
ret
|
||
jmp $ |