0

This code is supposed to print an integer in intel x86 assembly; however, when I run it, it produces no output and I don't know why. Also, I want someone to explain how can I retrieve an element from the stack properly as I don't quite understand the logic under the (next) label in the code

section .data
    msg db "Hello", 0xa
    len equ $ - msg 

section .text 

    global _start

_start:
    mov rax, 947852 ; the number that we are going to print 
    xor r10, r10    ; basically, makes rsi equal to 0 

    loop:
        xor rdx, rdx  ; zeroes the rdx to place the remainder in it
        mov rbx, 10 ; what we are going to divide by
        div rbx     ; div rax by rbx and places the remainder in rdx 
        add rdx, 48 ; convert it to its ascii equiavlent 
        push rdx    ; push this ascii on the stack 
        inc r10     ; a counter of the digits in the number we want to print
        cmp rax, 0  ; 
        jz next     ; if the number is now zero, then go to the fucntion that would print it in reverse 
        jmp loop

    next: 
        cmp r10, 0
        jz exit
        dec r10

        mov rax, 4 ; syscall for sys_Write
        mov rcx, rsp ;what we want to print
        mov rbx, 1 ; stdout as the destination
        mov rdx, 1 ; its size 
        int 0x80   ; interrupt the processor to perform the system call 
        add rsp, 1
        jmp next   ; loop again 

    exit:
        mov rax, 1   ; syscall for exiting properly 
        mov rbx, 0   ; error code 0
        int 0x80     ; interrupt to exit 

Mina Ashraf
  • 353
  • 1
  • 12
  • 1
    Do not use `int 0x80` system calls in 64 bit code. That's likely the cause of your problem. – fuz Mar 13 '20 at 21:43
  • Yup. `strace` should show `write` returning `-EFAULT`. `mov rcx, rsp` can't work for `int 0x80` because RSP has non-zero high bytes. – Peter Cordes Mar 13 '20 at 21:48
  • @PeterCordes I replaced them with syscalls and I still have the same problem. I also tried converting the code to 32 bit and leave the int 0x80 and nothing changed. I think the error is is that I do not pop from the stack what I had already pushed properly. Can you help in this part, please? – Mina Ashraf Mar 13 '20 at 22:35
  • @fuz it is not actually the problem, I think it has to do with handling the stack properly – Mina Ashraf Mar 13 '20 at 22:35
  • 1
    You might have other bugs *too*, but using `int 0x80` in 64-bit code was definitely a showstopper. Run `strace ./my_program` to see the memory contents pointed to by the pointers + lengths you're passing to `write` system calls. The 64-bit ABI uses different call numbers and registers, so if you *just* replaced int 0x80 with syscall then of course that wouldn't work. – Peter Cordes Mar 13 '20 at 23:05
  • [How do I print an integer in Assembly Level Programming without printf from the c library?](https://stackoverflow.com/a/46301894) shows how to convert an integer to a decimal ASCII string and write() it. And yes, you do have other bugs, e.g. `add rsp, 1` only pops 1 byte after you pushed 8-byte `rdx` – Peter Cordes Mar 13 '20 at 23:14
  • @MinaAshraf Please post your updated code using the `syscall` interface. We can reopen the question if that wasn't it. Note that there is more to it than just swapping `syscall` for `int 0x80`. – fuz Mar 13 '20 at 23:16

0 Answers0