printf: Support %i,%x,%X

This commit is contained in:
2025-07-09 11:34:19 +02:00
parent af34e3208c
commit e80b14c051
2 changed files with 56 additions and 8 deletions

View File

@@ -3,6 +3,7 @@
extern strlen extern strlen
extern dec2str extern dec2str
extern udec2str extern udec2str
extern hex2str
section .rodata section .rodata
mNL db NL mNL db NL
@@ -63,7 +64,10 @@ puts:
; %% Literal percentage sign ; %% Literal percentage sign
; %c Single character ; %c Single character
; %d Signed integer, printed as decimal ; %d Signed integer, printed as decimal
; %i Alias for %d
; %u Unsigned integer, printed as decimal ; %u Unsigned integer, printed as decimal
; %x Unsigned integer, printed as hexadecimal number (lowercase)
; %X Unsigned integer, printed as hexadecimal number (uppercase)
; %s String ; %s String
; <!> Unsupported specifiers are printed as-is ; <!> 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 ; <!> 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 ; rdi* (arg) pointer to format[] to format and print >> pointer to buffer
; rsi* (optional arg) >> Used for inserting strings to buffer ; rsi* (optional arg) >> Used for inserting strings to buffer
; rdx* (optional arg) >> Keeps track of amount of processed format specifiers ; 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 ; r8* (optional arg) >> Used for moving characters
; r9* (optional arg) >> Keeps track of where to jump after flushing buffer ; r9* (optional arg) >> Keeps track of where to jump after flushing buffer
; r10* Keeps track of current index of printfBuff ; r10* Keeps track of current index of printfBuff
@@ -119,10 +123,16 @@ printf:
je .rep_pct je .rep_pct
cmp byte [rdi + 1], 'c' cmp byte [rdi + 1], 'c'
je .rep_c je .rep_c
cmp byte [rdi + 1], 'i'
je .rep_d
cmp byte [rdi + 1], 'd' cmp byte [rdi + 1], 'd'
je .rep_d je .rep_d
cmp byte [rdi + 1], 'u' cmp byte [rdi + 1], 'u'
je .rep_d je .rep_d
cmp byte [rdi + 1], 'x'
je .rep_x
cmp byte [rdi + 1], 'X'
je .rep_x
cmp byte [rdi + 1], 's' cmp byte [rdi + 1], 's'
je .rep_s je .rep_s
@@ -150,7 +160,7 @@ printf:
mov rsi, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)] mov rsi, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)]
jmp .insertChar jmp .insertChar
;--- '%d' / '%u' ---; ;--- '%i' / '%d' / '%u' ---;
.rep_d: .rep_d:
cmp rdx, 4 cmp rdx, 4
ja .d_fromStack ja .d_fromStack
@@ -163,14 +173,14 @@ printf:
push rdx push rdx
push rdi push rdi
sub rsp, SIZE_QWORD sub rsp, SIZE_QWORD
cmp byte [rdi + 1], 'd' cmp byte [rdi + 1], 'u'
je .callINT2STR je .callUINT2STR
mov rdi, rsi
call udec2str
jmp .loadConvertedStr
.callINT2STR:
mov rdi, rsi mov rdi, rsi
call dec2str call dec2str
jmp .loadConvertedStr
.callUINT2STR:
mov rdi, rsi
call udec2str
.loadConvertedStr: .loadConvertedStr:
mov rsi, rax mov rsi, rax
add rsp, SIZE_QWORD add rsp, SIZE_QWORD
@@ -179,6 +189,32 @@ printf:
pop rax pop rax
jmp .insertString 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' ---; ;--- '%s' ---;
.rep_s: .rep_s:
cmp rdx, 4 cmp rdx, 4

View File

@@ -60,6 +60,8 @@ section .rodata
printf3C8 equ '!' printf3C8 equ '!'
printf4 db TAB,"printf(",DQUO,"%d|%u , %d|%u\n",DQUO,", -50, -50, 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF): ",NL,TAB,TAB,EOS 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 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() ; strlen()
strlenStr1 db "Hello",EOS strlenStr1 db "Hello",EOS
@@ -207,6 +209,16 @@ _start:
mov rcx, 0xFFFFFFFFFFFFFFFF mov rcx, 0xFFFFFFFFFFFFFFFF
mov r8, 0xFFFFFFFFFFFFFFFF mov r8, 0xFFFFFFFFFFFFFFFF
call printf 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 %endif
;--- ;---