2
; NASM
push 30 ; '0'

mov rax, 4 ; write
mov rbx, 1 ; stdout
mov rcx, rsp ; ptr to character on stack
mov rdx, 1 ; length of string = 1
int 80h

The code above does not print anything to stdout. It works when i give it a ptr to a character in section .data. What am i doing wrong?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847

2 Answers2

5

amd64 uses a different method for system calls than int 0x80, although that might still work with 32-bit libraries installed, etc. Whereas on x86 one would do:

mov eax, SYSCALL_NUMBER
mov ebx, param1
mov ecx, param2
mov edx, param3
int 0x80

on amd64 one would instead do this:

mov rax, SYSCALL_NUMBER_64 ; different from the x86 equivalent, usually
mov rdi, param1
mov rsi, param2
mov rdx, param3
syscall

For what you want to do, consider the following example:

        bits 64
        global _start

section .text

_start:
        push            0x0a424242
        mov             rdx, 04h
        lea             rsi, [rsp]
        call            write
        call            exit
exit:
        mov             rax, 60     ; exit()
        xor             rdi, rdi    ; errno
        syscall

write:
        mov             rax, 1      ; write()
        mov             rdi, 1      ; stdout
        syscall
        ret
Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
  • 1
    I think the reason his code worked with an address in `.data` is that `.data` starts at an address that fits in 32b, so it isn't affected by passing it through the x86 `int 0x80` ABI. The stack defaults to being mapped at a high address (where the high-bits are all 1s, rather than all 0s). – Peter Cordes Jul 13 '15 at 12:30
1

30 decimal is the code of the ASCII "record separator". Whatever that is, it's probably not a printable character.

30 hexadecimal (30h or 0x30 in NASM parlance), on the other hand, is the code of the ASCII "0".

Also, you need to use the 64-bit ABI.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • I did forget the h you are right, but after adding it its still not working. I even stepped through with gdb and rcx is being set to a ptr, when i query the value of that ptr it is 0x30 .... I have no idea what is wrong –  Apr 11 '12 at 12:48
  • In that case, I think you may be confusing the 32-bit ABI with the 64-bit ABI. See [this question/answer](http://stackoverflow.com/q/5022744/968261). – Alexey Frunze Apr 11 '12 at 13:06
  • If that's too long to read, [here's a short example of using the write syscall in 64-bit mode](http://www.cs.lmu.edu/~ray/notes/linuxsyscalls/). – Alexey Frunze Apr 11 '12 at 14:22