Watcom
The Watcom compiler suite is a powerful (reputed to produce the best optimized code for 16 and 32 bits programs by demosceners and game coders in end '90s) compiler/assembler/make/linker suite that comes with tools for binary files manipulations.
A few words of caution on using the compiler
The third party commercial tests that were used to test the compiler did not survive the compiler transition to opensource. IOW, for most practical uses they were lost. Because of that and because of the currently limited support the compiler isn't thoroughly tested nowadays and changes and bugfixes may introduce bugs into the compiler and the code it generates. FWIW, here are a few shameful and scary bugs discovered in the Open Watcom C/C++ 1.9 compiler while feeding it tests written for the Smaller C compiler. Those tests must've caught these:
- Crash while parsing declarations
- Compound assignment with division or modulo produces bogus results
- Ternary conditional operator isn't doing default conversions
- missing lvalue check
- comma operator not working when assigning structures
Creating a flat binary
OpenWatcom's linker WLink can produce flat binaries using command line options or a linker script. The options aren't well documented (see the linker section of the C++ master reference), but one of its maintainers helped in putting together an example linker script:
name kernel.bin # name of resulting binary output raw # type of binary (ELF, PE, MZ, PharLap, ...) offset=0x100000 # skip first meg; base address of binary file startup.obj # objects to link - this one has to be first file fdc.obj file gui.obj file idt.obj # add more obj files here order # in which order should segments be put into binary clname CODE offset=0x100000 # offset for reference fixups clname DATA
This linker script does not include the BSS class in the binary because its uninitialized data anyway and will only add unnecessary size to the resulting binary.
WLink executes a linker script from the command line as:
wlink @linkerscript.lnk
How can I tell Watcom to produce XXX files?
Natively, all Watcom C/C++ compilers can produce is OMF (.obj) files by default. (See this forum thread).
What are the differences between Watcom 11.0c and Open Watcom 1.3?
Not much; Open Watcom added a few new features.
Why is my final executable not in fact executable?
Watcom has a habit of inserting additional function calls in your code which are not necessarily available in the final binary. To work around this add the '-s' switch to the command line to disable stack overflow checking.
However the 32-bit C (Wcc386) and C++ (Wpp386) compiler insert function calls that the processor will flag as invalid, and if the interrupt controllers are not fixed the CPU will triple fault. This does not seem to be a problem with the 16-bit compilers. I am still trying to figure out how to bypass these calls.
Linking Watcom produced object files and linking them with JLOC causes some problems at runtime
Watcom makes DS follow the DS:DGROUP, and if you do not want that structure your going to have to fiddle with Jloc.