Files
klibc/console.asm

239 lines
3.7 KiB
NASM

extern NR_write
extern strlen
extern strcat
extern itoa
section .rodata
NL db 0xA
section .bss
printfBuff resb 4096
printfNBuff resb 32
section .text
global print
global puts
global printf
;----- print (char* string) -----;
; return value: N/A
print:
push rbp
mov rbp, rsp
call strlen
mov rdx, rax
mov rax, NR_write
mov rsi, rdi
mov rdi, 1
syscall
leave
ret
;----- puts (char* string) -----;
; return value: N/A
puts:
push rbp
mov rbp, rsp
mov r10, rdi
call print
mov rdi, r10
mov rax, NR_write
mov rdi, 1
mov rsi, NL
mov rdx, 1
syscall
leave
ret
;----- printf(const char* string, ...) -----;
; Currently only supports specifiers: %d, %c, %s, %%
; Return value: Amount of printed characters
printf:
push rbp
mov rbp, rsp
push r12
push r13
xor r10, r10
lea r11, [rel printfBuff]
.makeStr:
cmp byte [rdi], 0x0
je .finish
cmp byte [rdi], '%'
je .replaceArg
mov r12b, byte [rdi]
mov byte [r11], r12b
jmp .continue
.replaceArg:
cmp byte [rdi+1], 0x0
je .continue
push rdi
cmp byte [rdi+1], 'd'
je .rep_d
cmp byte [rdi+1], '%'
je .rep_pct
cmp byte [rdi+1], 'c'
je .rep_c
cmp byte [rdi+1], 's'
je .rep_s
;--- invalid specifier ---;
mov byte [r11], '%'
inc r10 ;assuming args were passed for invalid specifiers !
jmp .continue
;--- %d ---;
.rep_d:
cmp r10, 0
je .rep_d_rsi
cmp r10, 1
je .rep_d_rdx
cmp r10, 2
je .rep_d_rcx
cmp r10, 3
je .rep_d_r8
cmp r10, 4
je .rep_d_r9
;get from stack
mov rdi, qword [rbp + 16 + (r10-5)*8]
jmp .convertInt
.rep_d_rsi:
mov rdi, rsi
jmp .convertInt
.rep_d_rdx:
mov rdi, rdx
jmp .convertInt
.rep_d_rcx:
mov rdi, rcx
jmp .convertInt
.rep_d_r8:
mov rdi, r8
jmp .convertInt
.rep_d_r9:
mov rdi, r9
.convertInt:
lea rsi, [rel printfNBuff]
push rcx
push rdx
push r8
push r10
push rsi
call itoa
pop rsi
pop r10
pop r8
pop rdx
pop rcx
mov rsi, rax
jmp .insertLoop
;--- %% ---;
.rep_pct:
mov rdi, '%'
dec r10 ;r10 is increased at the end, but not needed because '%%' requires no arg
jmp .charToStr
;--- %c ---;
.rep_c:
cmp r10, 0
je .rep_c_rsi
cmp r10, 1
je .rep_c_rdx
cmp r10, 2
je .rep_c_rcx
cmp r10, 3
je .rep_c_r8
cmp r10, 4
je .rep_c_r9
;get from stack
mov rdi, qword [rbp + 16 + (r10-5)*8]
jmp .charToStr
.rep_c_rsi:
mov rdi, rsi
jmp .charToStr
.rep_c_rdx:
mov rdi, rdx
jmp .charToStr
.rep_c_rcx:
mov rdi, rcx
jmp .charToStr
.rep_c_r8:
mov rdi, r8
jmp .charToStr
.rep_c_r9:
mov rdi, r9
jmp .charToStr
.charToStr:
mov [printfNBuff], dil
mov dil, 0
mov [printfNBuff+1], dil
lea rsi, [rel printfNBuff]
jmp .insertLoop
;--- %s ---;
.rep_s:
cmp r10, 0
je .insertLoop ;nothing to do, rsi already correct
cmp r10, 1
je .rep_s_rdx
cmp r10, 2
je .rep_s_rcx
cmp r10, 3
je .rep_s_r8
cmp r10, 4
je .rep_s_r9
;get from stack
mov rsi, qword [rbp + 16 + (r10-5)*8]
jmp .insertLoop
.rep_s_rdx:
mov rsi, rdx
jmp .insertLoop
.rep_s_rcx:
mov rsi, rcx
jmp .insertLoop
.rep_s_r8:
mov rsi, r8
jmp .insertLoop
.rep_s_r9:
mov rsi, r9
;--- Move fetched data to buffer ---;
.insertLoop:
cmp byte [rsi], 0x0
je .s0f
mov r13b, byte [rsi]
mov byte [r11], r13b
inc rsi
inc r11
jmp .insertLoop
.s0f:
inc r10
pop rdi
add rdi, 2
jmp .makeStr
.continue:
inc rdi
inc r11
jmp .makeStr
.finish:
mov byte [r11], 0x0
lea rdi, [rel printfBuff]
call print
lea rdi, [rel printfBuff]
call strlen
pop r13
pop r12
leave
ret