diff --git a/src/console.asm b/src/console.asm index b82a98d..c38cd8d 100644 --- a/src/console.asm +++ b/src/console.asm @@ -3,6 +3,7 @@ extern strlen extern dec2str extern udec2str +extern hex2str section .rodata mNL db NL @@ -63,7 +64,10 @@ puts: ; %% Literal percentage sign ; %c Single character ; %d Signed integer, printed as decimal +; %i Alias for %d ; %u Unsigned integer, printed as decimal +; %x Unsigned integer, printed as hexadecimal number (lowercase) +; %X Unsigned integer, printed as hexadecimal number (uppercase) ; %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 @@ -72,7 +76,7 @@ puts: ; rdi* (arg) pointer to format[] to format and print >> pointer to buffer ; rsi* (optional arg) >> Used for inserting strings to buffer ; rdx* (optional arg) >> Keeps track of amount of processed format specifiers -; rcx* (optional arg) +; rcx* (optional arg) >> Stores arg for %x/%X ; 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 @@ -119,10 +123,16 @@ printf: je .rep_pct cmp byte [rdi + 1], 'c' je .rep_c + cmp byte [rdi + 1], 'i' + je .rep_d cmp byte [rdi + 1], 'd' je .rep_d cmp byte [rdi + 1], 'u' je .rep_d + cmp byte [rdi + 1], 'x' + je .rep_x + cmp byte [rdi + 1], 'X' + je .rep_x cmp byte [rdi + 1], 's' je .rep_s @@ -150,7 +160,7 @@ printf: mov rsi, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)] jmp .insertChar - ;--- '%d' / '%u' ---; + ;--- '%i' / '%d' / '%u' ---; .rep_d: cmp rdx, 4 ja .d_fromStack @@ -163,14 +173,14 @@ printf: push rdx push rdi sub rsp, SIZE_QWORD - cmp byte [rdi + 1], 'd' - je .callINT2STR - mov rdi, rsi - call udec2str - jmp .loadConvertedStr - .callINT2STR: + cmp byte [rdi + 1], 'u' + je .callUINT2STR mov rdi, rsi call dec2str + jmp .loadConvertedStr + .callUINT2STR: + mov rdi, rsi + call udec2str .loadConvertedStr: mov rsi, rax add rsp, SIZE_QWORD @@ -179,6 +189,32 @@ printf: pop rax jmp .insertString + ;--- '%x' / '%X' ---; + .rep_x: + push rdi + cmp rdx, 4 + ja .x_fromStack + mov rcx, [printfArgs + SIZE_QWORD * rdx] + jmp .convertHex + .x_fromStack: + mov rcx, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)] + .convertHex: + xor rsi, rsi + mov r8, 1 + cmp byte [rdi + 1], 'X' + cmove rsi, r8 + mov rdi, rcx + push rax + push rdx + push r9 + call hex2str + mov rsi, rax + pop r9 + pop rdx + pop rax + pop rdi + jmp .insertString + ;--- '%s' ---; .rep_s: cmp rdx, 4 diff --git a/src/tests.asm b/src/tests.asm index fb51025..62e2da1 100644 --- a/src/tests.asm +++ b/src/tests.asm @@ -60,6 +60,8 @@ section .rodata printf3C8 equ '!' printf4 db TAB,"printf(",DQUO,"%d|%u , %d|%u\n",DQUO,", -50, -50, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF): ",NL,TAB,TAB,EOS printf4Str db "%d|%u , %d|%u",NL,EOS + printf5 db TAB,"printf(",DQUO,"%x|%X , %x|%X\n",DQUO,", 0xabcdeffedcba, 0x069bc0e, 666, -1): ",NL,TAB,TAB,EOS + printf5Str db "%x|%X , %x|%X",NL,EOS ; strlen() strlenStr1 db "Hello",EOS @@ -207,6 +209,16 @@ _start: mov rcx, 0xFFFFFFFFFFFFFFFF mov r8, 0xFFFFFFFFFFFFFFFF call printf + + ; TEST 5 + lea rdi, [rel printf5] + call print + lea rdi, [rel printf5Str] + mov rsi, 0xabcdeffedcba + mov rdx, 0x069bc0e + mov rcx, 666 + mov r8, -1 + call printf %endif ;---