printf: Add padding support for %d, %i, %u, %x, %X

This commit is contained in:
2025-07-12 16:33:07 +02:00
parent b327248e0c
commit efeded5547
3 changed files with 176 additions and 58 deletions

View File

@@ -11,26 +11,27 @@ section .text
global hex2str
global bin2str
;----- dec2str(int) -----;
;----- dec2str(int, padLen, bool padZeroes) -----;
; Converts a signed integer to a string (decimal output)
; Return value: Pointer to string containing the converted integer
; Used registers:
; rax* int stored for div >> (ret) pointer to cnvtBuff[]
; rcx* Counts length of created string
; rdx* modulo as calculated by div >> character storage for cnvtBuff
; rdx* (arg) padZeroes >> modulo as calculated by div >> character storage for cnvtBuff
; rdi* (arg) integer to convert to string >> Remembers if num is negative
; rsi* Points to cnvtBuff for writing characters
; rsi* (arg) Padding length
; r8* Dividor for div
; r9* Points to cnvtBuff[]
; r10* padZeroes arg (since rdx used by DIV)
; r12 Remembers if number is negative
dec2str:
lea rsi, [rel cnvtBuffRev]
test rdi, rdi
jnz .notZero
lea rsi, [rel cnvtBuff]
mov byte [rsi], '0'
mov byte [rsi+1], EOS
jmp .quit
.notZero:
push r12
xor r12, r12
mov r10, ' '
mov r9, '0'
test rdx, rdx
cmovnz r10, r9
lea r9, [rel cnvtBuffRev]
mov rax, rdi
xor dil, dil
xor rcx, rcx
@@ -43,51 +44,78 @@ dec2str:
mov r8, 10
div r8
add rdx, '0'
mov [rsi], dl
inc rsi
mov [r9], dl
inc r9
inc rcx
test rax, rax
jnz .convert
test dil, dil
jz .makeString
mov [rsi], byte '-'
inc rcx
inc rsi
mov r12, 1
.makeString:
sub rsi, rcx
cmp rsi, rcx
jl .noPadding
mov r8, rcx
mov rdi, rsi
xor rsi, rsi
mov rdx, 64
call clamp
mov rcx, rax
test r12, r12
jz .paddingLoop
cmp r10, '0'
je .paddingLoop
mov byte [r9], '-'
inc r9
inc r8
xor r12, r12
.paddingLoop:
mov byte [r9], r10b
inc r9
inc r8
loop .paddingLoop
mov rcx, r8
.noPadding:
test r12, r12
jz .positive
mov [r9], byte '-'
inc r9
inc rcx
.positive:
lea rdi, [rel cnvtBuff]
dec rsi
dec r9
.makeStringLoop:
mov al, [rsi]
mov al, [r9]
mov [rdi], al
inc rdi
dec rsi
dec r9
loop .makeStringLoop
mov byte [rdi], EOS
.quit:
lea rax, [rel cnvtBuff]
pop r12
ret
;----- udec2str(uint) -----;
;----- udec2str(uint, padLen, bool padZeroes) -----;
; Converts an unsigned integer to a string (decimal output)
; Return value: Pointer to string containing the converted integer
; Used registers:
; rax* uint stored for div >> (ret) pointer to cnvtBuff[]
; rcx* Counts length of created string
; rdx* modulo as calculated by div >> character storage for cnvtBuff
; rdx* (arg) padZeroes >> modulo as calculated by div
; rdi* (arg) integer to convert to string
; rsi* Points to cnvtBuff for writing characters
; rsi* (arg) padLen
; r8* Dividor for div
; r9* Points to cnvtBuff for writing characters
; r10* padZeroes arg (since rdx used by DIV)
udec2str:
lea rsi, [rel cnvtBuffRev]
test rdi, rdi
jnz .notZero
lea rsi, [rel cnvtBuff]
mov byte [rsi], '0'
mov byte [rsi+1], EOS
jmp .quit
.notZero:
mov r10, ' '
mov r9, '0'
test rdx, rdx
cmovnz r10, r9
lea r9, [rel cnvtBuffRev]
mov rax, rdi
xor rcx, rcx
.convert:
@@ -95,18 +123,34 @@ udec2str:
mov r8, 10
div r8
add rdx, '0'
mov [rsi], dl
inc rsi
mov [r9], dl
inc r9
inc rcx
test rax, rax
jnz .convert
sub rsi, rcx
cmp rsi, rcx
jl .noPadding
mov r8, rcx
mov rdi, rsi
xor rsi, rsi
mov rdx, 64
call clamp
mov rcx, rax
.paddingLoop:
mov byte [r9], r10b
inc r9
inc r8
loop .paddingLoop
mov rcx, r8
.noPadding:
lea rdi, [rel cnvtBuff]
dec rsi
dec r9
.makeStringLoop:
mov al, [rsi]
mov al, [r9]
mov [rdi], al
inc rdi
dec rsi
dec r9
loop .makeStringLoop
mov byte [rdi], EOS
@@ -114,33 +158,31 @@ udec2str:
lea rax, [rel cnvtBuff]
ret
;----- hex2str(uint, bool uppercase) -----;
;----- hex2str(uint, bool uppercase, padLen, bool padZeroes) -----;
; Converts an unsigned integer to a string (hexadecimal output)
; Return value: Pointer to string containing the converted integer
; Used registers:
; rax* uint stored for div >> (ret) Pointer to cnvtBuff[]
; rdi (arg) Integer to convert
; rsi* (arg) 0=convert lowercase, (any other value)=convert uppercase >> Points to cnvtBuff for writing characters
; rdx* module as calculated by div
; rcx* Counts length of created string
; rdx* (arg) Padding length >> module as calculated by div
; rcx* (arg) padZeroes >> Counts length of created string
; r8* Dividor for div
; r9* Store arg rsi (uppercase)
; r10* Store arg rdx
; r11* Amount to add to number (for ASCII conversion, lowercase or uppercase)
; r12 Store arg padZeroes
hex2str:
push r12
mov r9, rsi
mov r10, rdx
mov r12, ' '
mov rsi, '0'
test rcx, rcx
cmovnz r12, rsi
lea rsi, [rel cnvtBuffRev]
test rdi, rdi
jnz .notZero
lea rsi, [rel cnvtBuff]
mov word [rsi], '0x'
mov byte [rsi + 2], '0'
mov byte [rsi + 3], EOS
jmp .quit
.notZero:
mov rax, rdi
xor rcx, rcx
mov r8, 87
test r9, r9
cmovz r11, r8
@@ -163,10 +205,25 @@ hex2str:
inc rcx
test rax, rax
jnz .convert
mov word [rsi], 'x0'
inc rsi
add rcx, 2
sub r10, rcx
cmp r10, rcx
jl .noPadding
mov r8, rcx
push rsi
mov rdi, r10
xor rsi, rsi
mov rdx, 64
call clamp
pop rsi
mov rcx, rax
.paddingLoop:
mov byte[rsi], r12b
inc rsi
inc r8
loop .paddingLoop
mov rcx, r8
.noPadding:
dec rsi
lea rdi, [rel cnvtBuff]
.makeString:
mov al, [rsi]
@@ -178,6 +235,7 @@ hex2str:
.quit:
lea rax, [rel cnvtBuff]
pop r12
ret
;----- bin2str(uint, padLen, bool padZeroes) -----;
@@ -223,14 +281,10 @@ bin2str:
cmp rsi, rcx
jl .noPadding
mov r8, rcx
push rsi
push rdx
mov rdi, rsi
xor rsi, rsi
mov rdx, 64
call clamp
pop rdx
pop rsi
mov rcx, rax
.paddingLoop:
mov byte [r9], r10b