And here for your reading pleasure is
hello.s. For this example we need to know only of the following bits of the ABI:
- The stack grows downwards (towards lower addresses) with
%rsppointing to the bottom of the stack.
%rspby 8, stores the address of the instruction after itself on the stack and then jumps to the address pointed to by its operand.
retinstruction jumps to the address pointed to by
%rspby 8 before resuming execution.
- Integer or pointer parameters to functions are passed in registers
%r9in that order and only if there are more than six such parameters is the stack used. An integer or pointer return value is returned in
/* A simple standalone hello world program. Usage: hello [arg] Prints "Hello $arg" if [arg] supplied, else "Hello world". */ .text /* We will link our program using gcc, which will take care of initialization and trasfer control to our 'main'. For this to work 'main' has to be marked as a symbol visible to the linker. */ .global main .type main, @function main: /* The ABI requires %rsp to be aligned to a 16-byte boundary just before a call. Since the %rsp is currently at a 8-byte boundary because of the return address from main, and because none of the calls we make pass any arguments on the stack, the following adjustment is enought for all the calls we make. */ subq $8, %rsp /*Compare argc to 1*/ cmpl $1,%edi jne .HAS_ARG movq $.DEF_GREET, %rsi jmp .PRINT .HAS_ARG: /*argv*/ movq 8(%rsi), %rsi .PRINT: movq $.FMT_STR, %rdi /*When calling variable argument functions like 'printf' we must place an upper bound on the number of vector arguments in %al*/ xorb %al,%al call printf /*Ready to return. Reverse our adjustment to %rsp */ addq $8,%rsp movq $0, %rax ret .section .rodata .FMT_STR: .string "hello %s\n" .DEF_GREET: .string "world"
The program above calls
printf and so has to be linked to the C library. I spent all afternoon feeding strange incantations to the GNU linker
ld to create a working executable. While I finally did get something which worked, I did not feel confident that I was doing exactly right. Finally I wimped out and called
gcc to do the linking, after seeing that even the famous
GHC did this. Here’s the
Next target, learning more about the instruction set, specially the SIMD instructions.