;----------------------------------------------------------------------------
; 64-bit helloworld in assembly, using printf() from C
;
; Equivalent to:
;       #include <stdio.h>
;       char msg[] = "Hello, world";
;       int main() {
;               printf("%s\n", msg);
;               return 0;
;       }
;
; Demonstrates basic text output using C printf(), in 64-bit mode.
;----------------------------------------
; Assemble in 64-bit:   nasm  -f elf64 -o hp64.o -l hp64.lst  hello-printf-64.asm
;
; Link:         ld hp64.o  -o hp64  -lc  --dynamic-linker /lib/ld-2.7.so
;   or maybe    ld hp64.o  -o hp64  -lc  --dynamic-linker /lib/ld-linux-x86-64.so.2
;       (the "-lc" option is needed to resolve "printf")
;
;   or else     gcc -o hp64  hp64.o
;       (but remove the "_start" label in this case, or gcc will complain)
;
; run:          ./hp64 
; output is:    Hello world,
;               ...and goodbye!
;----------------------------------------
; 2009-12-10 -bob,mon.
;----------------------------------------------------------------------------
        SECTION .data
msg:    db "Hello, world,", 0
msg2:   db "...and goodbye!", 0
fmt:    db "%s", 10, 0

        SECTION .text
        extern printf
        global main, _start
main:
_start:
        mov esi, msg    ; 64-bit ABI passing order starts w/ edi, esi, ...
        mov edi, fmt    ;
        mov eax, 0      ; printf is varargs, so EAX counts # of non-integer arguments being passed
        call printf

        mov esi, msg2   ; 64-bit ABI passing order starts w/ edi, esi, ...
        mov edi, fmt    ;
        mov eax, 0      ; printf is varargs, so EAX counts # of non-integer arguments being passed
        call printf

        mov ebx, 0      ; normal-exit code
        mov eax, 1      ; process-termination service
        int 0x80        ; linux kernel service
;----------------------------------------------------------------------------