That's kewl, Christian! Wish I'd had that years ago!
Someguy, you don't say what command line you're giving Nasm. "-f coff", and link it with DJGPP might almost have worked. I'm guessing "-f bin". When dos sees a filename ending in .com or .exe, it doesn't load it according to the extension (command.com has been an .exe for years!), but according to the signature in the first two bytes, if it's "MZ" (or "ZM", I'm told) it looks further for a "PE" signature to decide whether to load it as 16 bits or 32. If it doesn't see "MZ", it loads it as a 16 bit .com file. Regardless of how many bits you told Nasm!
An example might illustrate what you're up against...
; nasm -f bin -o myfile.com myfile.asm
bits 16
mov ax, bx
mov ax, 0A000h
nop
nop
nop
bits 32
mov ax, bx
mov eax, ebx
mov ax, 0A000h
mov eax, 0A000h
nop
nop
nop
Nasm will do both 16 and 32 in one shot. Ndisasm will not. By default, it'll disassemble as 16 bits - same as what your CPU will see if it's in 16-bit mode:
00000000 89D8 mov ax,bx
00000002 B800A0 mov ax,0xa000
00000005 90 nop
00000006 90 nop
00000007 90 nop
00000008 6689D8 mov eax,ebx
0000000B 89D8 mov ax,bx
0000000D 66B800A0B800 mov eax,0xb8a000
00000013 A00000 mov al,[0x0]
00000016 90 nop
00000017 90 nop
00000018 90 nop
As you can see, it gets a little confused when it gets to the part we told Nasm to assemble as "bits 32"! If you attempted to execute this code with the CPU in 32-bit mode, it'd see what "ndisasm -b 32 myfile.com" sees:
00000000 89D8 mov eax,ebx
00000002 B800A09090 mov eax,0x9090a000
00000007 90 nop
00000008 6689D8 mov ax,bx
0000000B 89D8 mov eax,ebx
0000000D 66B800A0 mov ax,0xa000
00000011 B800A00000 mov eax,0xa000
00000016 90 nop
00000017 90 nop
00000018 90 nop
Now the 16-bit part is wrong! You didn't have a 16-bit part in your attempt, but if you'd executed it with the CPU in 32-bit mode, when you did the "int 10h", it would be 16-bit code... which would be misinterpreted and you'd soon crash.
You can start off in 16-bit mode - a bootsector, say, or "real real-mode dos" - and switch the CPU to 32-bit (protected) mode, but you won't have int 10h... or any other interrupt, until you provide them. Since the hardware generates interrupts frequently, the first thing you'll do before entering pmode is "cli"... and don't "sti" until you've got some Interrupt Service Routines in place. I've never gotten that far...
Best,
Frank