Files
klibc/console.asm
2025-06-26 07:02:00 +02:00

225 lines
3.4 KiB
NASM

extern NR_write
extern strlen
extern strcat
extern itoa
section .rodata
NL db 0xA
bufferLength equ 4096
ERR_buffLen db "<!> ERROR: Failed to complete printf(), reached buffer length!",0xA,0x0
lERR_buffLen equ $-ERR_buffLen-1
section .bss
printfBuff resb bufferLength
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 r14
xor r10, r10
xor r14, r14
lea r11, [rel printfBuff]
.makeStr:
cmp byte [rdi], 0x0
je .finish
cmp r14, bufferLength-1
je .finish
cmp byte [rdi], '%'
je .replaceArg
mov r12b, byte [rdi]
mov byte [r11], r12b
inc r14
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 r14
inc r10
jmp .continue
;--- %d ---;
.rep_d:
cmp r10, 0
cmove rdi, rsi
je .convertInt
cmp r10, 1
cmove rdi, rdx
je .convertInt
cmp r10, 2
cmove rdi, rcx
je .convertInt
cmp r10, 3
cmove rdi, r8
je .convertInt
cmp r10, 4
cmove rdi, r9
je .convertInt
mov rdi, qword [rbp + 16 + (r10-5)*8]
.convertInt:
lea rsi, [rel printfNBuff]
push rcx
push rdx
push r8
push r10
call itoa
pop r10
pop r8
pop rdx
pop rcx
mov rsi, rax
jmp .insertLoop
;--- %% ---;
.rep_pct:
mov rdi, '%'
dec r10
jmp .charToStr
;--- %c ---;
.rep_c:
cmp r10, 0
cmove rdi, rsi
je .charToStr
cmp r10, 1
cmove rdi, rdx
je .charToStr
cmp r10, 2
cmove rdi, rcx
je .charToStr
cmp r10, 3
cmove rdi, r8
je .charToStr
cmp r10, 4
cmove rdi, r9
je .charToStr
mov rdi, qword [rbp + 16 + (r10-5)*8]
.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
cmp r10, 1
cmove rsi, rdx
je .insertLoop
cmp r10, 2
cmove rsi, rcx
je .insertLoop
cmp r10, 3
cmove rsi, r8
je .insertLoop
cmp r10, 4
cmove rsi, r9
je .insertLoop
mov rsi, qword [rbp + 16 + (r10-5)*8]
;--- Move fetched data to buffer ---;
.insertLoop:
cmp r14, bufferLength-1
je .finish
cmp byte [rsi], 0x0
je .s0f
mov r12b, byte [rsi]
mov byte [r11], r12b
inc r14
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
mov rax, NR_write
mov rdi, 1
lea rsi, [rel printfBuff]
mov rdx, r14
syscall
mov rax, r14
cmp r14, bufferLength-1
jl .final
mov rax, NR_write
mov rdi, 2
lea rsi, [rel ERR_buffLen]
mov rdx, lERR_buffLen
syscall
.final:
pop r14
pop r12
leave
ret