Adds basic printf() (currently only support '%%')
This commit is contained in:
116
src/console.asm
116
src/console.asm
@@ -4,9 +4,14 @@ extern strlen
|
|||||||
|
|
||||||
section .rodata
|
section .rodata
|
||||||
mNL db NL
|
mNL db NL
|
||||||
|
printfBuffLen equ 128
|
||||||
|
section .bss
|
||||||
|
printfBuff resb printfBuffLen
|
||||||
|
printfArgs resq 5
|
||||||
section .text
|
section .text
|
||||||
global print
|
global print
|
||||||
global puts
|
global puts
|
||||||
|
global printf
|
||||||
|
|
||||||
;----- print(*str[]) -----;
|
;----- print(*str[]) -----;
|
||||||
; Prints given string to the console to stdout
|
; Prints given string to the console to stdout
|
||||||
@@ -31,7 +36,10 @@ print:
|
|||||||
; Prints given string to the console to stdout and prints a new line
|
; Prints given string to the console to stdout and prints a new line
|
||||||
; Return value: Amount of printed characters
|
; Return value: Amount of printed characters
|
||||||
; Used registers:
|
; Used registers:
|
||||||
;
|
; rax* syscall >> (ret) amount of printed characters
|
||||||
|
; rdi* (arg) Pointer to str[] >> syscall arg (fd)
|
||||||
|
; rsi* syscall arg (pointer to str[])
|
||||||
|
; rdx* syscall arg (length of str[]+1)
|
||||||
puts:
|
puts:
|
||||||
sub rsp, SIZE_QWORD
|
sub rsp, SIZE_QWORD
|
||||||
call print
|
call print
|
||||||
@@ -45,3 +53,109 @@ puts:
|
|||||||
inc rax
|
inc rax
|
||||||
add rsp, SIZE_QWORD
|
add rsp, SIZE_QWORD
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;----- printf(*format[], ...) -----;
|
||||||
|
; Formats and prints given string to console to stdout
|
||||||
|
; Return value: Amount of printed characters
|
||||||
|
; Supported specifiers:
|
||||||
|
; %% Literal percentage sign
|
||||||
|
; <!> Unsupported specifiers are printed as-is
|
||||||
|
; Used registers:
|
||||||
|
; rax (ret) amount of printed characters
|
||||||
|
; rdi (arg) pointer to format[] to format and print
|
||||||
|
; rsi (optional arg)
|
||||||
|
; rdx (optional arg) >> Keeps track of amount of processed format specifiers
|
||||||
|
; rcx (optional arg)
|
||||||
|
; r8 (optional arg) >> Used for moving characters
|
||||||
|
; r9 (optional arg) >> Keeps track of where to jump after flushing buffer
|
||||||
|
; r10* Keeps track of current index of printfBuff
|
||||||
|
; r11* Keeps track of total characters (return value)
|
||||||
|
printf:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
sub rsp, SIZE_QWORD
|
||||||
|
|
||||||
|
cmp byte [rdi], EOS
|
||||||
|
je .emptyStr
|
||||||
|
|
||||||
|
xor r10, r10
|
||||||
|
xor r11, r11
|
||||||
|
|
||||||
|
; Store arguments to memory - easier to load data + more available registers (= less stack usage)
|
||||||
|
mov [printfArgs + SIZE_QWORD * 0], rsi
|
||||||
|
mov [printfArgs + SIZE_QWORD * 1], rdx
|
||||||
|
mov [printfArgs + SIZE_QWORD * 2], rcx
|
||||||
|
mov [printfArgs + SIZE_QWORD * 3], r8
|
||||||
|
mov [printfArgs + SIZE_QWORD * 4], r9
|
||||||
|
|
||||||
|
.process:
|
||||||
|
cmp byte [rdi], EOS
|
||||||
|
je .wrapup
|
||||||
|
mov r9b, 0
|
||||||
|
cmp r10, printfBuffLen-1
|
||||||
|
je .flushBuffer
|
||||||
|
.flushReturn_0:
|
||||||
|
cmp byte [rdi], '%'
|
||||||
|
je .argReplacement
|
||||||
|
mov r8b, [rdi]
|
||||||
|
mov [printfBuff+r10], r8b
|
||||||
|
inc r10
|
||||||
|
inc r11
|
||||||
|
inc rdi
|
||||||
|
jmp .process
|
||||||
|
|
||||||
|
.argReplacement:
|
||||||
|
cmp byte [rdi + 1], EOS
|
||||||
|
je .wrapup
|
||||||
|
cmp byte [rdi + 1], '%'
|
||||||
|
je .rep_pct
|
||||||
|
|
||||||
|
;--- Invalid ---;
|
||||||
|
mov r9w, word [rdi]
|
||||||
|
mov [printfBuff+r10], r9w
|
||||||
|
add rdi, 2
|
||||||
|
add r10, 2
|
||||||
|
add r11, 2
|
||||||
|
jmp .process
|
||||||
|
|
||||||
|
;--- '%%' ---;
|
||||||
|
.rep_pct:
|
||||||
|
mov [printfBuff+r10], byte '%'
|
||||||
|
add rdi, 2
|
||||||
|
add r10, 1
|
||||||
|
add r11, 1
|
||||||
|
jmp .process
|
||||||
|
|
||||||
|
|
||||||
|
.flushBuffer:
|
||||||
|
push rdx
|
||||||
|
push r11
|
||||||
|
mov rax, NR_write
|
||||||
|
mov rdi, FD_stdout
|
||||||
|
lea rsi, [rel printfBuff]
|
||||||
|
mov rdx, r11
|
||||||
|
syscall
|
||||||
|
pop r10
|
||||||
|
pop rdx
|
||||||
|
xor r10, r10
|
||||||
|
|
||||||
|
cmp r9b, 0
|
||||||
|
je .flushReturn_0
|
||||||
|
|
||||||
|
.wrapup:
|
||||||
|
mov rax, NR_write
|
||||||
|
mov rdi, FD_stdout
|
||||||
|
lea rsi, [rel printfBuff]
|
||||||
|
mov rdx, r10
|
||||||
|
mov r10, r11
|
||||||
|
syscall
|
||||||
|
mov rax, r10
|
||||||
|
jmp .quit
|
||||||
|
|
||||||
|
.emptyStr:
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
.quit:
|
||||||
|
add rsp, SIZE_QWORD
|
||||||
|
leave
|
||||||
|
ret
|
||||||
|
@@ -5,6 +5,7 @@ extern exit
|
|||||||
; console.asm
|
; console.asm
|
||||||
extern print
|
extern print
|
||||||
extern puts
|
extern puts
|
||||||
|
extern printf
|
||||||
; string.asm
|
; string.asm
|
||||||
extern strlen
|
extern strlen
|
||||||
extern strcpy
|
extern strcpy
|
||||||
@@ -14,6 +15,7 @@ extern strcat
|
|||||||
section .rodata
|
section .rodata
|
||||||
TEST_print equ 1
|
TEST_print equ 1
|
||||||
TEST_puts equ 1
|
TEST_puts equ 1
|
||||||
|
TEST_printf equ 1
|
||||||
TEST_strlen equ 1
|
TEST_strlen equ 1
|
||||||
TEST_strcpy equ 1
|
TEST_strcpy equ 1
|
||||||
TEST_strcat equ 1
|
TEST_strcat equ 1
|
||||||
@@ -30,6 +32,11 @@ section .rodata
|
|||||||
; puts()
|
; puts()
|
||||||
msgPuts db "TEST puts()",EOS
|
msgPuts db "TEST puts()",EOS
|
||||||
|
|
||||||
|
; printf()
|
||||||
|
msgPrintf db "TEST printf()",NL,EOS
|
||||||
|
printf1 db TAB,"printf(",DQUO,"He%ll%o there%%%%%!%s%!%\n",DQUO,"): ",NL,TAB,TAB,EOS
|
||||||
|
printf1Str db "He%ll%o there%%%%%!%s%!%",NL,EOS
|
||||||
|
|
||||||
; strlen()
|
; strlen()
|
||||||
strlenStr1 db "Hello",EOS
|
strlenStr1 db "Hello",EOS
|
||||||
strlenStr2 db "Hello, world!",NL,EOS
|
strlenStr2 db "Hello, world!",NL,EOS
|
||||||
@@ -75,6 +82,20 @@ _start:
|
|||||||
call puts
|
call puts
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
|
;---
|
||||||
|
;--- printf()
|
||||||
|
;---
|
||||||
|
%if TEST_printf
|
||||||
|
lea rdi, [rel msgPrintf]
|
||||||
|
call printf
|
||||||
|
|
||||||
|
; TEST 1
|
||||||
|
lea rdi, [rel printf1]
|
||||||
|
call print
|
||||||
|
lea rdi, [rel printf1Str]
|
||||||
|
call printf
|
||||||
|
%endif
|
||||||
|
|
||||||
;---
|
;---
|
||||||
;--- strlen()
|
;--- strlen()
|
||||||
;---
|
;---
|
||||||
|
Reference in New Issue
Block a user