Adds bin2str() and printf() format specifier %b

This commit is contained in:
2025-07-10 12:19:54 +02:00
parent e0bd8bcdbd
commit 902d962068
3 changed files with 125 additions and 20 deletions

View File

@@ -4,6 +4,7 @@ extern strlen
extern dec2str extern dec2str
extern udec2str extern udec2str
extern hex2str extern hex2str
extern bin2str
section .rodata section .rodata
mNL db NL mNL db NL
@@ -68,6 +69,7 @@ puts:
; %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 (lowercase)
; %X Unsigned integer, printed as hexadecimal number (uppercase) ; %X Unsigned integer, printed as hexadecimal number (uppercase)
; %b Unsigned integer, printed as binary number
; %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
@@ -132,6 +134,8 @@ printf:
je .rep_x je .rep_x
cmp byte [rdi + 1], 'X' cmp byte [rdi + 1], 'X'
je .rep_x je .rep_x
cmp byte [rdi + 1], 'b'
je .rep_b
cmp byte [rdi + 1], 's' cmp byte [rdi + 1], 's'
je .rep_s je .rep_s
@@ -214,6 +218,28 @@ printf:
pop rdi pop rdi
jmp .insertString jmp .insertString
;--- '%b' ---;
.rep_b:
cmp rdx, 4
ja .b_fromStack
mov rsi, [printfArgs + SIZE_QWORD * rdx]
jmp .convertBin
.b_fromStack:
mov rsi, [rbp + RBP_OFFSET_CALLER + ((rdx-5) * SIZE_QWORD)]
.convertBin:
sub rsp, SIZE_QWORD
push rax
push rdx
push rdi
mov rdi, rsi
call bin2str
mov rsi, rax
pop rdi
pop rdx
pop rax
add rsp, SIZE_QWORD
jmp .insertString
;--- '%s' ---; ;--- '%s' ---;
.rep_s: .rep_s:
cmp rdx, 4 cmp rdx, 4

View File

@@ -1,12 +1,13 @@
%include "src/constants.asm" %include "src/constants.asm"
section .bss section .bss
cnvtBuff resb 21 cnvtBuff resb 67
cnvtBuffRev resb 21 cnvtBuffRev resb 67
section .text section .text
global dec2str global dec2str
global udec2str global udec2str
global hex2str global hex2str
global bin2str
;----- dec2str(int) -----; ;----- dec2str(int) -----;
; Converts a signed integer to a string (decimal output) ; Converts a signed integer to a string (decimal output)
@@ -176,3 +177,52 @@ hex2str:
.quit: .quit:
lea rax, [rel cnvtBuff] lea rax, [rel cnvtBuff]
ret ret
;----- bin2str(uint) -----;
; Converts an unsigned integer to a string (binary 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
; rdi* (arg) integer to convert to string
; rsi* Points to cnvtBuff for writing characters
; r8* Dividor for div
bin2str:
lea rsi, [rel cnvtBuffRev]
test rdi, rdi
jnz .notZero
lea rsi, [rel cnvtBuff]
mov word [rsi], '0b'
mov byte [rsi + 2], '0'
mov byte [rsi + 3], EOS
jmp .quit
.notZero:
mov rax, rdi
xor rcx, rcx
.convert:
xor rdx, rdx
mov r8, 2
div r8
add rdx, '0'
mov [rsi], dl
inc rsi
inc rcx
test rax, rax
jnz .convert
mov word [rsi], 'b0'
add rcx, 2
inc rsi
lea rdi, [rel cnvtBuff]
.makeStringLoop:
mov al, [rsi]
mov [rdi], al
inc rdi
dec rsi
loop .makeStringLoop
mov byte [rdi], EOS
.quit:
lea rax, [rel cnvtBuff]
ret

View File

@@ -24,12 +24,14 @@ extern strcmp
extern dec2str extern dec2str
extern udec2str extern udec2str
extern hex2str extern hex2str
extern bin2str
section .rodata section .rodata
TEST_print equ 1 TEST_print equ 1
TEST_puts equ 1 TEST_puts equ 1
TEST_dec2str equ 1 ;includes udec2str TEST_dec2str equ 1 ;includes udec2str
TEST_hex2str equ 1 TEST_hex2str equ 1
TEST_bin2str equ 1
TEST_printf equ 1 TEST_printf equ 1
TEST_strlen equ 1 TEST_strlen equ 1
TEST_strcpy equ 1 TEST_strcpy equ 1
@@ -48,7 +50,7 @@ section .rodata
str3 db "Hello world!",EOS str3 db "Hello world!",EOS
str4 db "Howdy environment!",EOS str4 db "Howdy environment!",EOS
str5 db "The quick brown fox jumps over the lazy dog",EOS str5 db "The quick brown fox jumps over the lazy dog",EOS
msgStrings db "PRINT str1-5:",NL,"str1: %s",NL,"str2: %s",NL,"str3: %s",NL,"str4: %s",NL,"str5: %s",NL,NL,EOS msgStrings db "PRINT str1-5:",NL,"str1: %s",NL,"str2: %s",NL,"str3: %s",NL,"str4: %s",NL,"str5: %s",NL,EOS
; print() ; print()
msgPrint db NL,"TEST print()",NL,EOS msgPrint db NL,"TEST print()",NL,EOS
@@ -56,9 +58,12 @@ section .rodata
; puts() ; puts()
msgPuts db NL,"TEST puts()",EOS msgPuts db NL,"TEST puts()",EOS
; [u]dec2str() / hex2str() ; START LAZY SECTION
; [u]dec2str() / hex2str() / bin2str()
msgDec2str db NL,"TEST dec2str() / udec2str()",NL,TAB,"Use GDB ('x/s $rax' after function call)",NL,TAB,"No tests printed - see printf outputs :)",NL,EOS msgDec2str db NL,"TEST dec2str() / udec2str()",NL,TAB,"Use GDB ('x/s $rax' after function call)",NL,TAB,"No tests printed - see printf outputs :)",NL,EOS
msgHex2str db NL,"TEST hex2str()",NL,TAB,"Use GDB ('x/s $rax' after function call)",NL,TAB,"No tests printed - see printf outputs :)",NL,EOS msgHex2str db NL,"TEST hex2str()",NL,TAB,"Use GDB ('x/s $rax' after function call)",NL,TAB,"No tests printed - see printf outputs :)",NL,EOS
msgBin2str db NL,"TEST bin2str()",NL,TAB,"See min/max tests",NL,EOS ;Even more lazy
; END LAZY SECTION
; printf() ; printf()
msgPrintf db NL,"TEST printf()",NL,EOS msgPrintf db NL,"TEST printf()",NL,EOS
@@ -149,25 +154,25 @@ section .rodata
; min() / minu() ; min() / minu()
msgMin db NL,"TEST min(), minu()",NL,EOS msgMin db NL,"TEST min(), minu()",NL,EOS
min1 db TAB,"min(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS min1 db TAB,"min(15, 30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
min2 db TAB,"min(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS min2 db TAB,"min(-15, -30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
min3 db TAB,"min(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS min3 db TAB,"min(-1, 0):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
min4 db TAB,"min(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS min4 db TAB,"min(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
minu1 db TAB,"minu(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS minu1 db TAB,"minu(15, 30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
minu2 db TAB,"minu(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS minu2 db TAB,"minu(-15, -30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
minu3 db TAB,"minu(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS minu3 db TAB,"minu(-1, 0):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
minu4 db TAB,"minu(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS minu4 db TAB,"minu(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
; max() / maxu() ; max() / maxu()
msgMax db NL,"TEST max(), maxu()",NL,EOS msgMax db NL,"TEST max(), maxu()",NL,EOS
max1 db TAB,"max(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS max1 db TAB,"max(15, 30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
max2 db TAB,"max(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS max2 db TAB,"max(-15, -30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
max3 db TAB,"max(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS max3 db TAB,"max(-1, 0):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
max4 db TAB,"max(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS max4 db TAB,"max(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
maxu1 db TAB,"maxu(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS maxu1 db TAB,"maxu(15, 30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
maxu2 db TAB,"maxu(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS maxu2 db TAB,"maxu(-15, -30):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
maxu3 db TAB,"maxu(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS maxu3 db TAB,"maxu(-1, 0):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
maxu4 db TAB,"maxu(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS maxu4 db TAB,"maxu(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"[%d] (%x) (%b)",NL,EOS
section .data section .data
section .bss section .bss
@@ -264,6 +269,14 @@ _start:
call hex2str call hex2str
%endif %endif
;---
;--- bin2str()
;---
%if TEST_bin2str
lea rdi, [rel msgBin2str]
call print
%endif
;--- ;---
;--- printf() ;--- printf()
;--- ;---
@@ -739,6 +752,7 @@ _start:
lea rdi, [rel min1] lea rdi, [rel min1]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 2 ; TEST 2
@@ -748,6 +762,7 @@ _start:
lea rdi, [rel min2] lea rdi, [rel min2]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 3 ; TEST 3
@@ -757,6 +772,7 @@ _start:
lea rdi, [rel min3] lea rdi, [rel min3]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 4 ; TEST 4
@@ -766,6 +782,7 @@ _start:
lea rdi, [rel min4] lea rdi, [rel min4]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 1 ; TEST 1
@@ -775,6 +792,7 @@ _start:
lea rdi, [rel minu1] lea rdi, [rel minu1]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 2 ; TEST 2
@@ -784,6 +802,7 @@ _start:
lea rdi, [rel minu2] lea rdi, [rel minu2]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 3 ; TEST 3
@@ -793,6 +812,7 @@ _start:
lea rdi, [rel minu3] lea rdi, [rel minu3]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 4 ; TEST 4
@@ -802,6 +822,7 @@ _start:
lea rdi, [rel minu4] lea rdi, [rel minu4]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
%endif %endif
@@ -819,6 +840,7 @@ _start:
lea rdi, [rel max1] lea rdi, [rel max1]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 2 ; TEST 2
@@ -828,6 +850,7 @@ _start:
lea rdi, [rel max2] lea rdi, [rel max2]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 3 ; TEST 3
@@ -837,6 +860,7 @@ _start:
lea rdi, [rel max3] lea rdi, [rel max3]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 4 ; TEST 4
@@ -846,6 +870,7 @@ _start:
lea rdi, [rel max4] lea rdi, [rel max4]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 1 ; TEST 1
@@ -855,6 +880,7 @@ _start:
lea rdi, [rel maxu1] lea rdi, [rel maxu1]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 2 ; TEST 2
@@ -864,6 +890,7 @@ _start:
lea rdi, [rel maxu2] lea rdi, [rel maxu2]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 3 ; TEST 3
@@ -873,6 +900,7 @@ _start:
lea rdi, [rel maxu3] lea rdi, [rel maxu3]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
; TEST 4 ; TEST 4
@@ -882,6 +910,7 @@ _start:
lea rdi, [rel maxu4] lea rdi, [rel maxu4]
mov rsi, rax mov rsi, rax
mov rdx, rax mov rdx, rax
mov rcx, rax
call printf call printf
%endif %endif