>>108019404
doesn't really matter, you can fit a hello world in 100bytes of asm, but the linker will add extra linkage data and elf headers which is why it's usually ~16k. You can get it down to ~12k with little tweaking, but writing your own linker script will really make it smaller.
tiny.ld:
ENTRY(_start)
SECTIONS
{
. = 0x400000;
.text : { *(.text) }
/DISCARD/ : { *(.comment) *(.note*) *(.eh_frame*) }
}
a.c:
__attribute__((naked, noreturn))
void _start(void) {
asm volatile (
"mov $1, %rax\n\t"
"mov $1, %rdi\n\t"
"leaq hello_string(%rip), %rsi\n\t"
"mov $14, %rdx\n\t"
"syscall\n\t"
"mov $60, %rax\n\t"
"xor %rdi, %rdi\n\t"
"syscall\n"
"hlt\n"
);
}
const char hello_string[] __attribute__((section(".rodata"))) = "Hello, World!\n";
gcc -c -O2 -ffreestanding -nostdlib -fno-pie -o hello.o a.c
gcc -nostdlib -no-pie -o hello hello.o -Wl,-T,tiny.ld -Wl,-s
now, you can get it even smaller by using
gcc -nostdlib -no-pie -o hello hello.o -Wl,-T,tiny.ld -Wl,-N -Wl,-s
that would get it down to 4K (single segment)
but modern kernels won't allow a RWX LOAD segment, so it will crash, but it's technically correct