This would be a portable C (i.e. non x86-64, but still Linux) with just 2 syscalls:
$ cat a.c
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
void _start(void) {
syscall(__NR_write, 1, "Hello world!\n", 13);
syscall(__NR_exit_group, 1);
}
$ gcc -nostartfiles a.c -o a -static
$ ls -l a
-rwxr-xr-x 1 user user 9584 jan 5 00:07 a
$ strip -s a; ls -l a
-rwxr-xr-x 1 user user 9000 jan 5 00:10 a
$ strace ./a
execve("./a", ["./a"], 0x7ffd4d4f8250 /* 67 vars */) = 0
write(1, "Hello world!\n", 13) = 13
exit_group(1) = ?
+++ exited with 1 +++
I'm not actually sure why syscall() is inlined and glibc code is not included here while compiling with -static, but well, it works. Maybe it's because syscall() is a macro, or maybe it's some kind of ld code minimization (removing unused/unreachable code) trick which seems to be common in modern static linkers (ld, gold, lld).