From 4438abda11047f096539b289de1cac543c8f5d97 Mon Sep 17 00:00:00 2001 From: Kwarde Date: Wed, 25 Jun 2025 13:07:18 +0200 Subject: [PATCH] Dump current state of printf() (adding %d support), adds itoa() --- console.asm | 44 +++++++++++++++++++++++++++++++++++++++++--- core.asm | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests.asm | 44 +++++++++++++++++++++++--------------------- 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/console.asm b/console.asm index 834d6d5..9794263 100644 --- a/console.asm +++ b/console.asm @@ -1,11 +1,13 @@ extern NR_write extern strlen extern strcat +extern itoa section .rodata NL db 0xA section .bss printfBuff resb 4096 + printfNBuff resb 32 section .text global print global puts @@ -64,17 +66,53 @@ printf: .replaceArg: cmp byte [rdi+1], 0x0 je .continue + push rdi cmp byte [rdi+1], 'd' je .rep_d cmp byte [rdi+1], 's' je .rep_s + ;--- %d ---; .rep_d: - ;TODO - jmp .continue + cmp r10, 0 + je .rep_d_rsi + cmp r10, 1 + je .rep_d_rdx + cmp r10, 2 + je .rep_d_rcx + cmp r10, 3 + je .rep_d_r8 + cmp r10, 4 + je .rep_d_r9 + ;get from stack + ; rsp + 5*8 : RIP to printf call (+1), PUSH rbp,r12,r13,rdi (+4) + mov rsi, qword [rsp + 5*8 + (r10-5)*8] + jmp .convertInt + + .rep_d_rsi: + mov rdi, rsi + jmp .convertInt + .rep_d_rdx: + mov rdi, rdx + jmp .convertInt + .rep_d_rcx: + mov rdi, rcx + jmp .convertInt + .rep_d_r8: + mov rdi, r8 + jmp .convertInt + .rep_d_r9: + mov rdi, r9 + + .convertInt: + lea rsi, [rel printfNBuff] + call itoa + mov rsi, rax + jmp .sinsertLoop + + ;--- %s ---; .rep_s: - push rdi cmp r10, 0 je .sinsertLoop ;nothing to do, rsi already correct cmp r10, 1 diff --git a/core.asm b/core.asm index 9d77187..13a2a66 100644 --- a/core.asm +++ b/core.asm @@ -1,3 +1,5 @@ +extern strclr + section .text global min global minu @@ -7,6 +9,7 @@ section .text global isupper global tolower global toupper + global itoa ;----- min(int a, int b) -----; ; return value: lowest value @@ -120,3 +123,52 @@ toupper: .quit: leave ret +;----- itoa(int num, char* str) -----; +; return value: pointer to str +itoa: + push rbp + mov rbp, rsp + + push rsi + push rdi + mov rdi, rsi + call strclr + pop rdi + mov rax, rdi + mov r8, rsi + xor rcx, rcx + + test rax, rax + jnz .checkNeg + mov byte [rsi], '0' + mov byte [rsi+1], 0 + jmp .quit + + .checkNeg: + xor rbx, rbx + test rax, rax + jns .convert + neg rax + mov rbx, 1 + + .convert: + xor rdx, rdx + mov r10, 10 + div r10 + add rdx, '0' + push rdx + inc rcx + test rax, rax + jnz .convert + + .toString: + pop rdx + mov byte [rsi], dl + inc rsi + loop .toString + + .quit: + pop rsi + mov rax, rsi + leave + ret diff --git a/tests.asm b/tests.asm index e8c1481..51898f7 100644 --- a/tests.asm +++ b/tests.asm @@ -12,6 +12,7 @@ extern islower extern isupper extern tolower extern toupper +extern itoa ;console.asm extern print extern puts @@ -29,25 +30,25 @@ extern fclose extern fwrite section .rodata - PRINT_nums equ 0 + PRINT_nums equ 1 PRINT_strs equ 1 - TEST_print equ 0 - TEST_puts equ 0 + TEST_print equ 1 + TEST_puts equ 1 TEST_printf equ 1 - TEST_min equ 0 ;includes minu - TEST_max equ 0 ;includes maxu - TEST_strlen equ 0 - TEST_islower equ 0 - TEST_isupper equ 0 - TEST_strcpy equ 0 - TEST_strlcpy equ 0 - TEST_strclr equ 0 - TEST_strlclr equ 0 - TEST_strcat equ 0 - TEST_tolower equ 0 - TEST_toupper equ 0 - TEST_strcmp equ 0 - TEST_file1 equ 0 + TEST_min equ 1 ;includes minu + TEST_max equ 1 ;includes maxu + TEST_strlen equ 1 + TEST_islower equ 1 + TEST_isupper equ 1 + TEST_strcpy equ 1 + TEST_strlcpy equ 1 + TEST_strclr equ 1 + TEST_strlclr equ 1 + TEST_strcat equ 1 + TEST_tolower equ 1 + TEST_toupper equ 1 + TEST_strcmp equ 1 + TEST_file1 equ 1 num1 dq 69 num2 dq 0xFFFFFF @@ -68,7 +69,7 @@ section .rodata msgPuts db NL,NL,"# puts()",NL,EOS msgPuts1 db "puts() test",EOS ; printf() - testStr db "Testing: %s, %s, %s, %s, %s, %s, %s, %s, %s",NL,EOS + testStr db "Testing: %s, %s, %s, %s, %s, %s, %s, %s, %d, %s",NL,EOS tS1 db "one",EOS tS2 db "two",EOS tS3 db "three",EOS @@ -80,7 +81,7 @@ section .rodata tS9 db "noin",EOS msgPrintf db NL,"# printf()",EOS msgPrintf1 db "TEST printf()",NL,EOS - msgPrintf2 db "TEST printf(testStr, tS1, tS2, tS3, tS4, tS5, tS6, tS7, tS8, tS9)",NL,EOS + msgPrintf2 db "TEST printf(testStr, tS1, tS2, tS3, tS4, tS5, tS6, tS7, tS8, num1, tS9)",NL,EOS ; min() / minu() msgMin db NL,"# min() / minu()",EOS msgMin1 db "TEST min(num1, num2): %d",NL,EOS @@ -220,7 +221,7 @@ main: lea rdi, [rel msgPrintf1] call printf - ; TEST: printf(testStr, tS1, tS2, tS3, tS4, tS5, tS6, tS7, tS8, tS9) + ; TEST: printf(testStr, tS1, tS2, tS3, tS4, tS5, tS6, tS7, tS8, num1, tS9) lea rdi, [rel msgPrintf2] call printf @@ -231,11 +232,12 @@ main: lea r8, [rel tS4] lea r9, [rel tS5] push tS9 + push qword [num1] push tS8 push tS7 push tS6 call printf - add rsp, 32 ;cleanup stack, 8*4 + add rsp, 40 ;cleanup stack, 8*5 %ENDIF %IF TEST_min lea rdi, [rel msgMin]