How to write assembly language hello world program for 64 bit Mac OS X using printf?

32bit-64bit, 64-bit, assembly, macos, printf

Solution

You didn't say exactly what the problem you're seeing is, but I'm guessing that you're crashing at the point of the call to `printf`. This is because OS X (both 32- and 64-bit) requires that the stack pointer have 16-byte alignment at the point of any external function call.

The stack pointer was 16-byte aligned when `_main` was called; that call pushed an eight-byte return address onto the stack, so the stack is not 16-byte aligned at the point of the call to `_printf`. Subtract eight from `%rsp` before making the call in order to properly align it.

So I went ahead and debugged this for you (no magic involved, just use gdb, `break main`, `display/5i $pc`, `stepi`, etc). The other problem you're having is here:

movq _hello(%rip), %rdi

This loads the first eight bytes of your string into `%rdi`, which isn't what you want at all (in particular, the first eight bytes of your string are exceedingly unlikely to constitute a valid pointer to a format string, which results in a crash in `printf`). Instead, you want to load the address of the string. A debugged version of your program is:

.cstring
_hello: .asciz "Hello, world\n"

.text
.globl _main
_main:
    sub  $8, %rsp           // align rsp to 16B boundary
    mov  $0, %rax
    lea  _hello(%rip), %rdi // load address of format string
    call _printf            // call printf
    add  $8, %rsp           // restore rsp
    ret

Problem

I am trying to learn writing assembly language for 64 bit Mac OS. I have no problem with 32 bit Mac OS and both 32 bit and 64 bit Linux. However, Mac OS 64 bit is different and I couldn't figure out. Therefore I am here to ask for help. I have not problem using system call to print. However, I would like to learn how to call C functions using 64 bit assembly language of Mac OS. Please look at the following code ``` .data _hello: .asciz "Hello, world\n" .text .globl _main _main: movq $0, %rax movq _hello(%rip), %rdi call _printf ``` I use $ gcc -arch x86_64 hello.s to assemble and link. It generates binary code. However, I got a segmentation fault when running it. I tried adding "subq $8, %rsp" before calling _printf, still the same result as before. What did I do wrong? By the way, is that any way to debug this code on Mac? I tried adding -ggdb or -gstab or -gDWARF, and $gdb ./a.out, and can't see the code and set break points.

Original source

Related problems