diff --git a/src/console.asm b/src/console.asm index b6c0aaa..14bf615 100644 --- a/src/console.asm +++ b/src/console.asm @@ -7,7 +7,7 @@ section .rodata printfBuffLen equ 128 section .bss printfBuff resb printfBuffLen - printfArgs resq 5 + printfArgs resq 5 ;5=>rsi,rdx,rcx,r8,r9 section .text global print global puts @@ -59,15 +59,17 @@ puts: ; Return value: Amount of printed characters ; Supported specifiers: ; %% Literal percentage sign +; %s String ; Unsupported specifiers are printed as-is +; For all specifiers (except %%) an argument is expected. Mismatch between arguments given and specifiers provided will lead to issues ; 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 +; rax* (ret) amount of printed characters +; rdi* (arg) pointer to format[] to format and print +; rsi* (optional arg) >> Used for inserting strings to buffer +; 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 +; 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: @@ -77,16 +79,17 @@ printf: 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 + mov [rel printfArgs + SIZE_QWORD * 0], rsi + mov [rel printfArgs + SIZE_QWORD * 1], rdx + mov [rel printfArgs + SIZE_QWORD * 2], rcx + mov [rel printfArgs + SIZE_QWORD * 3], r8 + mov [rel printfArgs + SIZE_QWORD * 4], r9 + + xor rdx, rdx + xor r10, r10 + xor r11, r11 .process: cmp byte [rdi], EOS @@ -109,6 +112,8 @@ printf: je .wrapup cmp byte [rdi + 1], '%' je .rep_pct + cmp byte [rdi + 1], 's' + je .rep_s ;--- Invalid ---; mov r9w, word [rdi] @@ -125,22 +130,55 @@ printf: add r10, 1 add r11, 1 jmp .process - + + ;--- '%s' ---; + .rep_s: + cmp rdx, 4 + ja .s_fromStack + mov rsi, [printfArgs + SIZE_QWORD * rdx] + jmp .insertString + .s_fromStack: + lea rsi, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)] + + ;--- Insert string to buffer ---; + .insertString: + cmp byte [rsi], EOS + je .endInsertString + mov r9b, 1 + cmp r10, printfBuffLen-1 + je .flushBuffer + .flushReturn_1: + mov r8b, byte [rsi] + mov [printfBuff + r10], r8b + inc rsi + inc r10 + inc r11 + jmp .insertString + .endInsertString: + inc rdx + add rdi, 2 + jmp .process .flushBuffer: + push rdi + push rsi push rdx push r11 mov rax, NR_write mov rdi, FD_stdout lea rsi, [rel printfBuff] - mov rdx, r11 + mov rdx, r10 syscall - pop r10 + pop r11 pop rdx + pop rsi + pop rdi xor r10, r10 cmp r9b, 0 je .flushReturn_0 + cmp r9b, 1 + je .flushReturn_1 .wrapup: mov rax, NR_write diff --git a/src/tests.asm b/src/tests.asm index e13e17f..410de79 100644 --- a/src/tests.asm +++ b/src/tests.asm @@ -34,8 +34,12 @@ section .rodata ; 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 + printf1 db TAB,"printf(",DQUO,"He%ll%o there%%%%%!%!%\n",DQUO,"): ",NL,TAB,TAB,EOS + printf1Str db "He%ll%o there%%%%%!%!%",NL,EOS + printf2 db TAB,"printf(",DQUO,"Are %s doing %s?\n",DQUO,", printf2Str1, printf2Str2): ",NL,TAB,TAB,EOS + printf2Str db "Are %s doing %s?",NL,EOS + printf2Str1 db "you",EOS + printf2Str2 db "okay",EOS ; strlen() strlenStr1 db "Hello",EOS @@ -94,6 +98,14 @@ _start: call print lea rdi, [rel printf1Str] call printf + + ; TEST 2 + lea rdi, [rel printf2] + call print + lea rdi, [rel printf2Str] + lea rsi, [rel printf2Str1] + lea rdx, [rel printf2Str2] + call printf %endif ;---