3

I am running FreeBSD 11.0.

The following from the FreeBSD manual does NOT print the "Hello, World!" message:

section .text
hello db 'Hello, World!, 0Ah
hbytes equ $-hello

_syscall:
    int 80h
    ret

global _start
_start:
    push dword hbytes
    push dword hello
    push dword 1   ; stdout
    mov rax, 4    ; write syscall
    call _syscall
    add rsp, byte 24 ; restore stack
    push word 0      ; return 0
    mov rax, 1       ; exit call
    call _syscall

But this works:

section .text
hello db 'Hello, World!, 0Ah
hbytes equ $-hello

_syscall:
    int 80h
    ret

global _start
_start:
    mov rdi, 1
    mov rsi, hello  ; appears to be magic
    mov rdx, hbytes ; appears to be magic
    mov rax, 4    ; write syscall
    call _syscall

    push word 0      ; return 0
    mov rax, 1       ; exit call
    call _syscall

This raises couple questions:

1) Why doesn't the first approach work?

The UNIX calling convention is push data on the stack. Program does not crash. I just don't get any output, and the program terminates. I am compiling and linking fine.

2) How are we supposed to know about what registers to load, and with what values?

If I was pushing on the stack, it is easy. I look up the C functions and then I know how to push data.

In this case, it works like magic.

3) Where is the documentation for FreeBSD for similar system calls (not utilizing stack)??!

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Makketronix
  • 1,389
  • 1
  • 11
  • 31
  • 1
    `push rax, 4` doesn't even make sense. Anyway, I am guessing [freebsd also uses the standard sysv abi](https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI), I am sure you can google that ;) – Jester Jul 31 '17 at 19:39
  • You are correct. I was typing manually from the virtual machine. I don't have copy/paste setup yet :) – Makketronix Jul 31 '17 at 19:41
  • You are mixing up the 32-bit and 64-bit calling conventions. In 64-bit code you use `syscall` instruction,not `int 0x80`. In 64-bit code get rid of the `call _syscall` and just use `syscall` instruction – Michael Petch Jul 31 '17 at 19:56
  • Thanks for the info. I can keep asking thousand whys. Where would I get this information though? That's my main struggle. (Note, I am investigating System V ABIs) – Makketronix Jul 31 '17 at 19:57
  • 1
    This answer has link to information for the System V x86-64 ABI: https://stackoverflow.com/a/2538212/3857942 Particularly: https://refspecs.linuxbase.org/elf/x86-64-abi-0.99.pdf – Michael Petch Jul 31 '17 at 20:06
  • The ABI will at least tell you what registers you use to pass data to a `syscall` instruction. If you want to see a list of the FreeBSD system call numbers and their parameters you may wish to see this: https://github.com/freebsd/freebsd/blob/master/sys/kern/syscalls.master – Michael Petch Jul 31 '17 at 20:09
  • So the question is, is FreeBSD 100% compliant with System V. I read somewhere on their mailing list that it kernel-usersland is not 100% compliant on saving some registers, which is fixed in their libc. Link: https://lists.freebsd.org/pipermail/freebsd-arch/2011-April/011245.html – Makketronix Jul 31 '17 at 20:14
  • 1
    The X86-64 System V ABI with regards to **system calls** is the same. – Michael Petch Jul 31 '17 at 20:20
  • Thank you Michael. If that is in the answer I can accept it. – Makketronix Jul 31 '17 at 20:21
  • I think this is more or less a duplicate of this SO answer: https://stackoverflow.com/a/2538212/3857942 – Michael Petch Jul 31 '17 at 20:23
  • 1
    Yeah, I agree. It is unfortunate that that result didn't turn soon enough. – Makketronix Jul 31 '17 at 20:27

0 Answers0