I did a similar thing to run an MS-DOS executable on Linux. I couldn’t use DosBox because I need to redirect the input/output to another program, and writing the code to load and run the DOS executable was easier than trying to modify DosBox.
Since it doesn’t work on original 16-bit DOS files, why not keep the same spirit, but redefine it slightly to make it easier to work? So instead of starting at address 100, start at address 1000 maybe, mmap the file directly, don’t have to change the sysctl setting, and run with it. That’d be kinda fun.
I agree, this is a bit too obfuscated to be practical. I do love the idea of small binaries though. Maybe something like this is more suitable for it: https://github.com/gynvael/asmloader
See also the discussion on proggit: https://www.reddit.com/r/programming/comments/bpnwa0/linux_loader_for_flat_binary_dos_like_com_files/
I had to change the inline assembly in loader.c a bit to get this to work (it was jumping to a relative address causing an illegal instruction instead of branching directly to 0x100)
"mov $0x10000, %rsp\n"
"mov $0x100, %rax\n"
Just loading the 0x100 branch target address into RAX and jumping to it indirectly.
This post could use some upvotes on hackernews: https://news.ycombinator.com/item?id=19936838