; fasmg hello.asm hello && chmod 755 hello && ./hello; echo $? macro mov.d target, source match =eax?, target db 0xB8 dd source else match =edi?, target db 0xBF dd source else match =rax?, target db 0x48, 0xC7, 0xC0 dd source else match =rdi, target db 0x48, 0xC7, 0xC7 dd source else assert 0 end match end macro macro mov.q target, source match =rdi, target db 0x48, 0xBF dq source else match =rsi, target db 0x48, 0xBE dq source else match =rdx, target db 0x48, 0xBA dq source else assert 0 end match end macro macro syscall db 0x0F, 0x05 ; 0f two-byte escape ; 05 syscall ^ o64 end macro org 0x08048000 elf_header: ; * denotes mandatory fields according to breadbox db 0x7F, "ELF" ; *magic number db 2 ; 64-bit db 1 ; little-endian db 1 ; ELF header format version 1 db 0 ; System-V ABI db 8 dup 0 ; (padding) dw 2 ; *executable dw 0x3E ; *Intel x86-64 dd 1 ; ELF format version dq _start ; *entry point dq program_header - $$ ; *program header offset dq 0 ; section header offset dd 0 ; processor flags dw elf_header_size dw program_header_entry_size ; * dw 1 ; *number of program header entries dw 0 ; section header entry size dw 0 ; number of section header entries dw 0 ; section name string table index elf_header_size = $ - elf_header program_header: dd 1 ; *"loadable" segment type dd 0x05 ; *read+execute permission dq 0 ; *offset in file dq $$ ; *virtual address ; required, but can be anything, subject to ; alignment dq 0 ; physical address (ignored) dq file_size ; *size in file dq file_size ; *size in memory dq 0 ; segment alignment ; for relocation - will we be ASLR'd? program_header_entry_size = $ - program_header _start: mov.d eax, 1 mov.q rdi, 1 mov.q rsi, greeting mov.q rdx, greeting_size syscall mov.d eax, 60 mov.d edi, 0 syscall greeting: db "Hello, Irenes!", 0x0A greeting_size = $ - greeting file_size = $ - $$