diff --git a/src/console.asm b/src/console.asm index be0197b..fcac7e0 100644 --- a/src/console.asm +++ b/src/console.asm @@ -4,6 +4,7 @@ extern strlen extern dec2str extern udec2str extern hex2str +extern bin2str section .rodata mNL db NL @@ -68,6 +69,7 @@ puts: ; %u Unsigned integer, printed as decimal ; %x Unsigned integer, printed as hexadecimal number (lowercase) ; %X Unsigned integer, printed as hexadecimal number (uppercase) +; %b Unsigned integer, printed as binary number ; %s String ; 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 @@ -132,6 +134,8 @@ printf: je .rep_x cmp byte [rdi + 1], 'X' je .rep_x + cmp byte [rdi + 1], 'b' + je .rep_b cmp byte [rdi + 1], 's' je .rep_s @@ -214,6 +218,28 @@ printf: pop rdi 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' ---; .rep_s: cmp rdx, 4 diff --git a/src/convert.asm b/src/convert.asm index 97a6758..97aaf3e 100644 --- a/src/convert.asm +++ b/src/convert.asm @@ -1,12 +1,13 @@ %include "src/constants.asm" section .bss - cnvtBuff resb 21 - cnvtBuffRev resb 21 + cnvtBuff resb 67 + cnvtBuffRev resb 67 section .text global dec2str global udec2str global hex2str + global bin2str ;----- dec2str(int) -----; ; Converts a signed integer to a string (decimal output) @@ -176,3 +177,52 @@ hex2str: .quit: lea rax, [rel cnvtBuff] 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 diff --git a/src/tests.asm b/src/tests.asm index 74ffd80..fcf6502 100644 --- a/src/tests.asm +++ b/src/tests.asm @@ -24,12 +24,14 @@ extern strcmp extern dec2str extern udec2str extern hex2str +extern bin2str section .rodata TEST_print equ 1 TEST_puts equ 1 TEST_dec2str equ 1 ;includes udec2str TEST_hex2str equ 1 + TEST_bin2str equ 1 TEST_printf equ 1 TEST_strlen equ 1 TEST_strcpy equ 1 @@ -48,7 +50,7 @@ section .rodata str3 db "Hello world!",EOS str4 db "Howdy environment!",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() msgPrint db NL,"TEST print()",NL,EOS @@ -56,9 +58,12 @@ section .rodata ; puts() 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 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() msgPrintf db NL,"TEST printf()",NL,EOS @@ -149,25 +154,25 @@ section .rodata ; min() / minu() msgMin db NL,"TEST min(), minu()",NL,EOS - min1 db TAB,"min(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS - min2 db TAB,"min(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS - min3 db TAB,"min(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS - min4 db TAB,"min(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS - minu1 db TAB,"minu(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS - minu2 db TAB,"minu(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS - minu3 db TAB,"minu(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS - minu4 db TAB,"minu(0xFFFFFFFF, -4294967295):",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) (%b)",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) (%b)",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) (%b)",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) (%b)",NL,EOS ; max() / maxu() msgMax db NL,"TEST max(), maxu()",NL,EOS - max1 db TAB,"max(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS - max2 db TAB,"max(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS - max3 db TAB,"max(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS - max4 db TAB,"max(0xFFFFFFFF, -4294967295):",NL,TAB,TAB,"%d (%x)",NL,EOS - maxu1 db TAB,"maxu(15, 30):",NL,TAB,TAB,"%d (%x)",NL,EOS - maxu2 db TAB,"maxu(-15, -30):",NL,TAB,TAB,"%d (%x)",NL,EOS - maxu3 db TAB,"maxu(-1, 0):",NL,TAB,TAB,"%d (%x)",NL,EOS - maxu4 db TAB,"maxu(0xFFFFFFFF, -4294967295):",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) (%b)",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) (%b)",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) (%b)",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) (%b)",NL,EOS section .data section .bss @@ -264,6 +269,14 @@ _start: call hex2str %endif +;--- +;--- bin2str() +;--- +%if TEST_bin2str + lea rdi, [rel msgBin2str] + call print +%endif + ;--- ;--- printf() ;--- @@ -739,6 +752,7 @@ _start: lea rdi, [rel min1] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 2 @@ -748,6 +762,7 @@ _start: lea rdi, [rel min2] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 3 @@ -757,6 +772,7 @@ _start: lea rdi, [rel min3] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 4 @@ -766,6 +782,7 @@ _start: lea rdi, [rel min4] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 1 @@ -775,6 +792,7 @@ _start: lea rdi, [rel minu1] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 2 @@ -784,6 +802,7 @@ _start: lea rdi, [rel minu2] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 3 @@ -793,6 +812,7 @@ _start: lea rdi, [rel minu3] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 4 @@ -802,6 +822,7 @@ _start: lea rdi, [rel minu4] mov rsi, rax mov rdx, rax + mov rcx, rax call printf %endif @@ -819,6 +840,7 @@ _start: lea rdi, [rel max1] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 2 @@ -828,6 +850,7 @@ _start: lea rdi, [rel max2] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 3 @@ -837,6 +860,7 @@ _start: lea rdi, [rel max3] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 4 @@ -846,6 +870,7 @@ _start: lea rdi, [rel max4] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 1 @@ -855,6 +880,7 @@ _start: lea rdi, [rel maxu1] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 2 @@ -864,6 +890,7 @@ _start: lea rdi, [rel maxu2] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 3 @@ -873,6 +900,7 @@ _start: lea rdi, [rel maxu3] mov rsi, rax mov rdx, rax + mov rcx, rax call printf ; TEST 4 @@ -882,6 +910,7 @@ _start: lea rdi, [rel maxu4] mov rsi, rax mov rdx, rax + mov rcx, rax call printf %endif