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
3
  • 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. Commented Jun 2, 2022 at 19:23
  • @vitsoft The endianess of the number is wrong! 0x0000000028323C46 should be 0x00000000463C3228. Commented Jun 3, 2022 at 12:22
  • @SepRoland Mea culpa, thanks, I noticed but later than 5 min. Both numbers are rubish anyway. Commented Jun 3, 2022 at 16:58

1 Answer 1

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.