printf(): Add support for %s, fix buffer flushing (length given was r11, not r10)
This commit is contained in:
@@ -7,7 +7,7 @@ section .rodata
|
|||||||
printfBuffLen equ 128
|
printfBuffLen equ 128
|
||||||
section .bss
|
section .bss
|
||||||
printfBuff resb printfBuffLen
|
printfBuff resb printfBuffLen
|
||||||
printfArgs resq 5
|
printfArgs resq 5 ;5=>rsi,rdx,rcx,r8,r9
|
||||||
section .text
|
section .text
|
||||||
global print
|
global print
|
||||||
global puts
|
global puts
|
||||||
@@ -59,15 +59,17 @@ puts:
|
|||||||
; Return value: Amount of printed characters
|
; Return value: Amount of printed characters
|
||||||
; Supported specifiers:
|
; Supported specifiers:
|
||||||
; %% Literal percentage sign
|
; %% Literal percentage sign
|
||||||
|
; %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
|
||||||
; Used registers:
|
; Used registers:
|
||||||
; rax (ret) amount of printed characters
|
; rax* (ret) amount of printed characters
|
||||||
; rdi (arg) pointer to format[] to format and print
|
; rdi* (arg) pointer to format[] to format and print
|
||||||
; rsi (optional arg)
|
; 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)
|
||||||
; 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
|
||||||
; r11* Keeps track of total characters (return value)
|
; r11* Keeps track of total characters (return value)
|
||||||
printf:
|
printf:
|
||||||
@@ -78,16 +80,17 @@ printf:
|
|||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .emptyStr
|
je .emptyStr
|
||||||
|
|
||||||
|
; Store arguments to memory - easier to load data + more available registers (= less stack usage)
|
||||||
|
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 r10, r10
|
||||||
xor r11, r11
|
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
|
|
||||||
|
|
||||||
.process:
|
.process:
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .wrapup
|
je .wrapup
|
||||||
@@ -109,6 +112,8 @@ printf:
|
|||||||
je .wrapup
|
je .wrapup
|
||||||
cmp byte [rdi + 1], '%'
|
cmp byte [rdi + 1], '%'
|
||||||
je .rep_pct
|
je .rep_pct
|
||||||
|
cmp byte [rdi + 1], 's'
|
||||||
|
je .rep_s
|
||||||
|
|
||||||
;--- Invalid ---;
|
;--- Invalid ---;
|
||||||
mov r9w, word [rdi]
|
mov r9w, word [rdi]
|
||||||
@@ -126,21 +131,54 @@ printf:
|
|||||||
add r11, 1
|
add r11, 1
|
||||||
jmp .process
|
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:
|
.flushBuffer:
|
||||||
|
push rdi
|
||||||
|
push rsi
|
||||||
push rdx
|
push rdx
|
||||||
push r11
|
push r11
|
||||||
mov rax, NR_write
|
mov rax, NR_write
|
||||||
mov rdi, FD_stdout
|
mov rdi, FD_stdout
|
||||||
lea rsi, [rel printfBuff]
|
lea rsi, [rel printfBuff]
|
||||||
mov rdx, r11
|
mov rdx, r10
|
||||||
syscall
|
syscall
|
||||||
pop r10
|
pop r11
|
||||||
pop rdx
|
pop rdx
|
||||||
|
pop rsi
|
||||||
|
pop rdi
|
||||||
xor r10, r10
|
xor r10, r10
|
||||||
|
|
||||||
cmp r9b, 0
|
cmp r9b, 0
|
||||||
je .flushReturn_0
|
je .flushReturn_0
|
||||||
|
cmp r9b, 1
|
||||||
|
je .flushReturn_1
|
||||||
|
|
||||||
.wrapup:
|
.wrapup:
|
||||||
mov rax, NR_write
|
mov rax, NR_write
|
||||||
|
@@ -34,8 +34,12 @@ section .rodata
|
|||||||
|
|
||||||
; printf()
|
; printf()
|
||||||
msgPrintf db "TEST printf()",NL,EOS
|
msgPrintf db "TEST printf()",NL,EOS
|
||||||
printf1 db TAB,"printf(",DQUO,"He%ll%o there%%%%%!%s%!%\n",DQUO,"): ",NL,TAB,TAB,EOS
|
printf1 db TAB,"printf(",DQUO,"He%ll%o there%%%%%!%!%\n",DQUO,"): ",NL,TAB,TAB,EOS
|
||||||
printf1Str db "He%ll%o there%%%%%!%s%!%",NL,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()
|
; strlen()
|
||||||
strlenStr1 db "Hello",EOS
|
strlenStr1 db "Hello",EOS
|
||||||
@@ -94,6 +98,14 @@ _start:
|
|||||||
call print
|
call print
|
||||||
lea rdi, [rel printf1Str]
|
lea rdi, [rel printf1Str]
|
||||||
call printf
|
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
|
%endif
|
||||||
|
|
||||||
;---
|
;---
|
||||||
|
Reference in New Issue
Block a user