printf(): Allow padding (spaces or zeroes) for %b
This commit is contained in:
@@ -1,10 +0,0 @@
|
|||||||
%include "src/constants.asm"
|
|
||||||
extern printf
|
|
||||||
section .rodata
|
|
||||||
msg db "%133769666b",NL,EOS
|
|
||||||
section .text
|
|
||||||
global _start
|
|
||||||
_start:
|
|
||||||
lea rdi, [rel msg]
|
|
||||||
mov rsi, 6
|
|
||||||
call printf
|
|
@@ -84,6 +84,7 @@ puts:
|
|||||||
; 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)
|
||||||
; r12 Padding for numbers (0=nopadding, >0=padding w/ spaces, NOT >0=padding w/ zeroes)
|
; r12 Padding for numbers (0=nopadding, >0=padding w/ spaces, NOT >0=padding w/ zeroes)
|
||||||
|
; r13 Padding: zeroes (=1) or spaces (=0)
|
||||||
printf:
|
printf:
|
||||||
%macro load_arg 1
|
%macro load_arg 1
|
||||||
cmp rdx, 4
|
cmp rdx, 4
|
||||||
@@ -100,9 +101,13 @@ printf:
|
|||||||
push rax
|
push rax
|
||||||
push rdx
|
push rdx
|
||||||
push rdi
|
push rdi
|
||||||
|
push r9
|
||||||
|
push r10
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
%macro pop_regs 0
|
%macro pop_regs 0
|
||||||
|
pop r10
|
||||||
|
pop r9
|
||||||
pop rdi
|
pop rdi
|
||||||
pop rdx
|
pop rdx
|
||||||
pop rax
|
pop rax
|
||||||
@@ -112,6 +117,8 @@ printf:
|
|||||||
; entry:
|
; entry:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .emptyStr
|
je .emptyStr
|
||||||
@@ -148,14 +155,16 @@ printf:
|
|||||||
je .wrapup
|
je .wrapup
|
||||||
cmp byte [rdi + 1], '%'
|
cmp byte [rdi + 1], '%'
|
||||||
je .rep_pct
|
je .rep_pct
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
xor r13, r13
|
||||||
cmp byte [rdi + 1], '1' ;zero padding later!
|
mov r12, 1
|
||||||
|
cmp byte [rdi + 1], '0'
|
||||||
jb .noPadding
|
jb .noPadding
|
||||||
|
cmove r13, r12
|
||||||
cmp byte [rdi + 1], '9'
|
cmp byte [rdi + 1], '9'
|
||||||
jg .noPadding
|
jg .noPadding
|
||||||
|
xor r12, r12
|
||||||
inc rdi ;point to after '%'
|
xor rcx, rcx
|
||||||
xor rcx, rcx ;length of padding number (set to 0 first)
|
inc rdi
|
||||||
.findPaddingNumLen:
|
.findPaddingNumLen:
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .wrapup
|
je .wrapup
|
||||||
@@ -167,11 +176,10 @@ printf:
|
|||||||
inc rdi
|
inc rdi
|
||||||
jmp .findPaddingNumLen
|
jmp .findPaddingNumLen
|
||||||
.getPadding:
|
.getPadding:
|
||||||
dec rdi ;dont break .noPadding below (for cmp rdi+1)
|
dec rdi
|
||||||
push rdi
|
push rdi
|
||||||
push rax
|
push rax
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
xor r12, r12 ;total len
|
|
||||||
mov r9, 1
|
mov r9, 1
|
||||||
.getPaddingLoop:
|
.getPaddingLoop:
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
@@ -186,10 +194,10 @@ printf:
|
|||||||
mov r9, rax
|
mov r9, rax
|
||||||
loop .getPaddingLoop
|
loop .getPaddingLoop
|
||||||
pop rax
|
pop rax
|
||||||
pop rdi ;r12 should now store padding length
|
pop rdi
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
test r13, r13
|
||||||
; OK so at this point, padding (spaces, zeroes not yet supported) length is calculated correctly and string is replaced correctly.
|
jz .noPadding
|
||||||
; Now what remains is to actually add the spaces (and zeroes, eventually)
|
not r12
|
||||||
.noPadding:
|
.noPadding:
|
||||||
cmp byte [rdi + 1], 'c'
|
cmp byte [rdi + 1], 'c'
|
||||||
je .rep_c
|
je .rep_c
|
||||||
@@ -270,6 +278,20 @@ printf:
|
|||||||
load_arg rsi
|
load_arg rsi
|
||||||
push_regs
|
push_regs
|
||||||
mov rdi, rsi
|
mov rdi, rsi
|
||||||
|
;
|
||||||
|
mov rdx, 0
|
||||||
|
test r12, r12
|
||||||
|
jz .callB2S
|
||||||
|
test r12, r12
|
||||||
|
js .notB2S
|
||||||
|
jmp .callB2S
|
||||||
|
.notB2S:
|
||||||
|
not r12
|
||||||
|
mov rdx, 1
|
||||||
|
jmp .callB2S
|
||||||
|
;
|
||||||
|
.callB2S:
|
||||||
|
mov rsi, r12
|
||||||
call bin2str
|
call bin2str
|
||||||
mov rsi, rax
|
mov rsi, rax
|
||||||
pop_regs
|
pop_regs
|
||||||
@@ -342,6 +364,7 @@ printf:
|
|||||||
xor rax, rax
|
xor rax, rax
|
||||||
|
|
||||||
.quit:
|
.quit:
|
||||||
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
%include "src/constants.asm"
|
%include "src/constants.asm"
|
||||||
|
|
||||||
|
extern clamp
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
cnvtBuff resb 67
|
cnvtBuff resb 67
|
||||||
cnvtBuffRev resb 67
|
cnvtBuffRev resb 67
|
||||||
@@ -178,24 +180,30 @@ hex2str:
|
|||||||
lea rax, [rel cnvtBuff]
|
lea rax, [rel cnvtBuff]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
;----- bin2str(uint) -----;
|
;----- bin2str(uint, padLen, bool padZeroes) -----;
|
||||||
; Converts an unsigned integer to a string (binary output)
|
; Converts an unsigned integer to a string (binary output)
|
||||||
; Return value: Pointer to string containing the converted integer
|
; Return value: Pointer to string containing the converted integer
|
||||||
; Used registers:
|
; Used registers:
|
||||||
; rax* uint stored for div >> (ret) pointer to cnvtBuff[]
|
; rax* uint stored for div >> (ret) pointer to cnvtBuff[]
|
||||||
; rcx* Counts length of created string
|
; rcx* Counts length of created string
|
||||||
; rdx* modulo as calculated by div >> character storage for cnvtBuff
|
; rdx* (arg) If padLen>0, use Zeroes (rdx!=0) or spaces (rdx=0) >> modulo as calculated by div >> character storage for cnvtBuff
|
||||||
; rdi* (arg) integer to convert to string
|
; rdi* (arg) integer to convert to string
|
||||||
; rsi* Points to cnvtBuff for writing characters
|
; rsi* (arg) Padding length
|
||||||
; r8* Dividor for div
|
; r8* Dividor for div
|
||||||
|
; r9* Points to cnvtBuff for writing characters
|
||||||
|
; r10* padZeroes arg (since rdx used by DIV)
|
||||||
bin2str:
|
bin2str:
|
||||||
lea rsi, [rel cnvtBuffRev]
|
mov r10, ' '
|
||||||
|
mov r9, '0'
|
||||||
|
test rdx, rdx
|
||||||
|
cmovnz r10, r9
|
||||||
|
lea r9, [rel cnvtBuffRev]
|
||||||
test rdi, rdi
|
test rdi, rdi
|
||||||
jnz .notZero
|
jnz .notZero
|
||||||
lea rsi, [rel cnvtBuff]
|
lea r9, [rel cnvtBuff]
|
||||||
mov word [rsi], '0b'
|
mov word [r9], '0b'
|
||||||
mov byte [rsi + 2], '0'
|
mov byte [r9 + 2], '0'
|
||||||
mov byte [rsi + 3], EOS
|
mov byte [r9 + 3], EOS
|
||||||
jmp .quit
|
jmp .quit
|
||||||
|
|
||||||
.notZero:
|
.notZero:
|
||||||
@@ -206,20 +214,38 @@ bin2str:
|
|||||||
mov r8, 2
|
mov r8, 2
|
||||||
div r8
|
div r8
|
||||||
add rdx, '0'
|
add rdx, '0'
|
||||||
mov [rsi], dl
|
mov [r9], dl
|
||||||
inc rsi
|
inc r9
|
||||||
inc rcx
|
inc rcx
|
||||||
test rax, rax
|
test rax, rax
|
||||||
jnz .convert
|
jnz .convert
|
||||||
mov word [rsi], 'b0'
|
sub rsi, rcx
|
||||||
add rcx, 2
|
cmp rsi, rcx
|
||||||
inc rsi
|
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
|
||||||
|
inc r9
|
||||||
|
inc r8
|
||||||
|
loop .paddingLoop
|
||||||
|
mov rcx, r8
|
||||||
|
.noPadding:
|
||||||
|
dec r9
|
||||||
lea rdi, [rel cnvtBuff]
|
lea rdi, [rel cnvtBuff]
|
||||||
.makeStringLoop:
|
.makeStringLoop:
|
||||||
mov al, [rsi]
|
mov al, [r9]
|
||||||
mov [rdi], al
|
mov [rdi], al
|
||||||
inc rdi
|
inc rdi
|
||||||
dec rsi
|
dec r9
|
||||||
loop .makeStringLoop
|
loop .makeStringLoop
|
||||||
mov byte [rdi], EOS
|
mov byte [rdi], EOS
|
||||||
|
|
||||||
|
@@ -10,6 +10,8 @@ extern min
|
|||||||
extern minu
|
extern minu
|
||||||
extern max
|
extern max
|
||||||
extern maxu
|
extern maxu
|
||||||
|
extern clamp
|
||||||
|
extern clampu
|
||||||
; console.asm
|
; console.asm
|
||||||
extern print
|
extern print
|
||||||
extern puts
|
extern puts
|
||||||
@@ -88,6 +90,8 @@ section .rodata
|
|||||||
printf4Str db "%i|%d|%u , %i|%d|%u",NL,EOS
|
printf4Str db "%i|%d|%u , %i|%d|%u",NL,EOS
|
||||||
printf5 db TAB,"printf(",DQUO,"%x|%X , %x|%X\n",DQUO,", 0xabcdeffedcba, 0x069bc0e, 666, -1): ",NL,TAB,TAB,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
|
printf5Str db "%x|%X , %x|%X",NL,EOS
|
||||||
|
printf6 db TAB,"printf(",DQUO,"%b | %8b | %08b\n",DQUO,", 5, 5, 5): ",NL,TAB,TAB,EOS
|
||||||
|
printf6Str db "%b | %8b | %08b",NL,EOS
|
||||||
|
|
||||||
; strlen()
|
; strlen()
|
||||||
msgStrlen db NL,"TEST strlen()",NL,EOS
|
msgStrlen db NL,"TEST strlen()",NL,EOS
|
||||||
@@ -337,6 +341,15 @@ _start:
|
|||||||
mov rcx, 666
|
mov rcx, 666
|
||||||
mov r8, -1
|
mov r8, -1
|
||||||
call printf
|
call printf
|
||||||
|
|
||||||
|
; TEST 6
|
||||||
|
lea rdi, [rel printf6]
|
||||||
|
call print
|
||||||
|
lea rdi, [rel printf6Str]
|
||||||
|
mov rsi, 5
|
||||||
|
mov rdx, 5
|
||||||
|
mov rcx, 5
|
||||||
|
call printf
|
||||||
%endif
|
%endif
|
||||||
|
|
||||||
;---
|
;---
|
||||||
|
Reference in New Issue
Block a user