> Just try to write a hello world of that size nowadays!
The only reason why hello world binaries are bloated is because compilers for several compiled-to-native languages statically link many standard library functions into the final output executable.
You can write a hello world DOS terminal program[1] for x86, using the DOS syscall 9 (invoked with interrupt 21h)[2]:
format MZ
push cs
pop ds
mov ah,9
mov dx,hello
int 21h
mov ax,4C00h
int 21h
hello db 'Hello world!',24h
This would compile down to a handful of bytes.
Alternatively, if you want to use modern Windows syscalls (instead of legacy DOS syscalls), you can dynamically link to the Windows system libraries, and implement the hello world like so[3]:
format PE console ; Win32 portable executable console format
entry _start ; _start is the program's entry point
include 'INCLUDE/WIN32A.INC'
section '.data' data readable writable ; data definitions
hello db "Hello World!", 0
stringformat db "%s", 0ah, 0
section '.code' code readable executable ; code
_start:
invoke printf, stringformat, hello ; call printf, defined in msvcrt.dll
invoke getchar ; wait for any key
invoke ExitProcess, 0 ; exit the process
section '.imports' import data readable ; data imports
library kernel, 'kernel32.dll',\ ; link to kernel32.dll, msvcrt.dll
msvcrt, 'msvcrt.dll'
import kernel, \ ; import ExitProcess from kernel32.dll
ExitProcess, 'ExitProcess'
import msvcrt, \ ; import printf and getchar from msvcrt.dll
printf, 'printf',\
getchar, '_fgetchar'
This too would likely be under a kilobyte.
All of this uses fasm (flat assembler)[4][5].
[1] Source: https://board.flatassembler.net/topic.php?t=1736
[2] DOS syscalls: http://spike.scu.edu.au/~barry/interrupts.html
[3] Source: https://en.wikibooks.org/wiki/X86_Assembly/FASM_Syntax#Hello...
[4] https://flatassembler.net/
[5] https://en.wikipedia.org/wiki/FASM