0

I'm trying to print the third value of my array but I cant figure out how to print the value and not some crazy random number

I can print numbers 0-9 with just the normal technique but printing bigger numbers does not work. When i was debugging it showed that in printNumber the eax register was the memory address of numbers when it should have been the value

here's the code:


section .data
    numbers db 20, 30, 40, 50, 60, 70

section .text
    global _start

    _start:
        
        mov r8, numbers + 2

        printNumber [r8]        ; prints 117835012
        printNumber 3000        ; prints 3000

printNumber macro:

section .bss
    digit resb 0

%macro printNumber 1
    mov eax, %1

    %%printInt:
        mov rcx, digit      ;set rcx to digit memory address
        mov rbx, 10         ; moving a newline into rbx
        mov [rcx], rbx      ; setting digit to rbx
        inc rcx             ; increment rcx position by one byte

    %%storeLoop:
        xor rdx, rdx        ; zero out rdx
        mov rbx, 10         
        div rbx             ; rax / rbx (10)

                            ; rdx holds the remainder of the divison
        add rdx, 48         ; add 48 to rdx to make in ascii character
                            
        mov [rcx], dl       ; get the character part of rdx
        inc rcx             ; increment digit position again

        cmp rax, 0
        jnz %%storeLoop       ; continue looping until rax is 0

    %%printLoop:
        push rcx

        ;perform sys write
        mov rax, SYSWRITE
        mov rdi, 1
        mov rsi, rcx
        mov rdx, 1
        syscall

        pop rcx
        dec rcx
        cmp rcx, digit      ; first byte of digit (10)
        jge %%printLoop

%endmacro
user259137
  • 85
  • 1
  • 1
  • 2
    After you have loaded `eax` with `[r8]` (in the first line of your macro), you actually loaded `rax` with the number `0x0000000028323C46`. This is not the value that should be divided by ten in `%%storeLoop`. You should also reserve more bytes than 0 for `digit`. – vitsoft Jun 02 '22 at 19:23
  • @vitsoft The endianess of the number is wrong! 0x0000000028323C46 should be 0x00000000463C3228. – Sep Roland Jun 03 '22 at 12:22
  • @SepRoland Mea culpa, thanks, I noticed but later than 5 min. Both numbers are rubish anyway. – vitsoft Jun 03 '22 at 16:58

1 Answers1

2

Why did you not already improve your code regarding the post-increment vs pre-decrement issue for which I provided an answer in your previous question Assembly prints character before a big number ?

The invokation printNumber [r8] leads to the instruction mov eax, [r8] for the macro line that reads mov eax, %1. This mov instruction will load a dword from memory, and because your numbers array is composed of byte-sized elements, you will have combined 4 of these into one big number: RAX = 0x00000000463C3228.

Solution 1 is to define the array holding dwords, but it requires changing the offset that is used to address the 3rd element.

section .data
    numbers dd 20, 30, 40, 50, 60, 70

section .text
    global _start

    _start:
        
        mov r8, numbers + 8
        printNumber [r8]          ; -> mov eax, [r8]

Solution 2 is to keep the array byte-sized, but make sure to feed a dword value to the macro

section .data
    numbers db 20, 30, 40, 50, 60, 70

section .text
    global _start

    _start:
        
        movzx r8d, byte [numbers + 2]
        printNumber r8d           ; -> mov eax, r8d
Sep Roland
  • 33,889
  • 7
  • 43
  • 76