3 ms·
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
by wtarreau 7y ago
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, which doesn't even deliver the same work faster due to the tremendous waste of resource caused by laziness and incompetence.
- winter_blue 7y ago> 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 https://board.flatassembler.net/topic.php?t=1736 [2] DOS syscalls: http://spike.scu.edu.au/~barry/interrupts.html http://spike.scu.edu.au/~barry/interrupts.html [3] Source: https://en.wikibooks.org/wiki/X86_Assembly/FASM_Syntax#Hello_World https://en.wikibooks.org/wiki/X86_Assembly/FASM_Syntax#Hello... [4] https://flatassembler.net/ https://flatassembler.net/ [5] https://en.wikipedia.org/wiki/FASM https://en.wikipedia.org/wiki/FASM
- wtarreau 7y agoIt's also how I used to code under DOS (except using int 20h to exit and save 3 bytes, plus not copying CS into DS since .com has both equal). But my point precisely is that in order to provide such small binaries, you have to 1) have the skills, and 2) accept to think. Now many devs look up for obvious responses on stackoverflow before even making the effort of solving the problem by themselves, and as a result they inherit from tons of dependencies that cannot be removed and add huge stacks of functions with absolutely zero benefit for their use case.