printf: Support %i,%x,%X
This commit is contained in:
@@ -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
|
||||||
|
@@ -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
|
||||||
|
|
||||||
;---
|
;---
|
||||||
|
Reference in New Issue
Block a user