Not working on Mac, but I'm gonna tweet it anyway :)
movq $0x2000004, %rax ; // BSD syscalls are divided into classes.
movq $1, %rdi ; // 64-bit registers use %rdi instead of %ebx
lea message(%rip), %rsi; // Relative Address of message
movq $13, %rdx ; // Same Length
syscall ; // x86-64 ASM syscall
movq $0x2000001, %rax ; // Exit Syscall
movq $0, %rdi;
syscall
message: .ascii "Hello World!\n"; echo 'const int main[]={3850979413,184,3234285568,33554436,29869896,1207959552,1652109,3343384576,3522,1208291072,114887,3343385088,199,1208291072,1869376613,1919899424,169960556};'>t.c&&gcc t.c&&./a.out
But it is too long to tweet[Edit]
Less compact but more readable:
echo 'const int main[] = { 3850979413, 184, 3234285568, 33554436, 29869896, 1207959552, 1652109, 3343384576, 3522, 1208291072, 114887, 3343385088, 199, 1208291072, 1869376613, 1919899424, 169960556};' > test.c && gcc -Wall test.c -o test && ./test echo 'const int main[]={1208,114434,2370306048,2101,834048,84869120,1818577091,1461743468,1684828783,10};'|cc -xc -ot -&&./t
The trick is to use retq instead of a sys call to exit and to strip some of the code that the compiler create when you call a function (pushq %rpb; moveq %rsp, %rbp; movl $0x0, eax;)