Earlier quoted context omitted.
The 8086 introduced the abomination of segment registers. That created many software limitations for much of the 80's. Compilers with 64 K limits on array sizes, or code segment sizes, and similar. By comparison the 680x0 on classic Mac was a pleasure to program. A nice large simple flat address space.
segment registers were a cheap MMU before its age. It was the only way to run code without relocation tables at various addresses. Mind you that at this era the whole operating system fitted in 40kB of RAM! My old turbo-pascal 3.0 editor+compiler was something around 37 kB! Just try to write a hello world of that size nowadays! It's pointless to criticize the past based on 10000 times more powerful hardware 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...