I generally don't like to post in idiotic renamed threads that should not have been created (rather the posts should have been deleted), but I make an exception to answer the below
AbstractYouShudNow wrote:So you wrote a system in only assembly language ?
I think at this time, any OS developper had to work with only an assembler and the Intel's manuals.
Originally, I used MASM, and Microsofts linker that naturally outputed DOS executables. Since the linker assumed the executable was for real-mode, any segment relocations would be faulty, so the implied rule was that no "SEG" operators was allowed. The linker couldn't combine several modules into a kernel either as it would be confined to 64k, which was too little even for an assembly-only project. That was initially why the syscalls and between kernel-modules was written like they were in order to be able to do run-time relocation by patching the code. Since quite some time now, using DOS executables for device-drivers is no longer used (except for the initial "kernel", which must use this format in order to be compatible with loaders. Today, device-drivers are native and can be both 16-bit and 32-bit segmented (but not flat). The new C device-drivers are 32-bit, and so is the PE loader (which is in assembly).
This background also lead me to write an IA32 emulator. As this was before Bochs and Virtual PC, that was the only way to debug the startup-code. The same code was also used to emulate the first page in DOS, as this was required when running multiple DOS processes. I still have a device-driver that can emulate instructions.