FP Emulation Instructions
When disassembling DOS programs, floating point instructions are often replaced by set of interrupts that emulate the floating point instruction if the computer does not have floating point hardware. If the computer does have floating point hardware, then the int is replaced after the first call with a native opcode.Good disassemblers convert the interrupt opcodes to FP instructions automatically now.
The interrupts and the equivalent native opcodes are as follows:
| Interrupt | Opcode |
|---|---|
| 34h | D8h |
| 35h | D9h |
| 36h | DAh |
| 37h | DBh |
| 38h | DCh |
| 39h | DDh |
| 3Ah | DEh |
| 3Bh | DFh |
| 3Dh | FWAIT |
Reversed Operand FP Instructions
Intel have a slightly confusing way of naming their instructions. This shows up especially in the FSUB and FDIV instructions, when using the ST(i),ST addressing mode in combination with the "R" variant.For example:
| Instruction | opcode | Semantics |
|---|---|---|
| FSUB ST,STi | D8 E0+i | ST := ST - STi |
| FSUBR ST,STi | D8 E8+i | ST := STi - ST |
| FSUB STi,ST | DC E8+i | STi := STi - ST |
| FSUBR STi,ST | DC E0+i | STi := ST - STi |
This means that FSUB and FSUBR are swapped in the DE and DC tables relative to the D8 table. (DE opcodes are as per DC but with "POP" ("P" appended to opcode)). Few disassemblers get this right; IDA Pro is one of the few that do get it right.
The same applies to the FDIV series of instructions.
To add to the confusion, some of the early Intel manuals got FSUB wrong (and yet FDIV right). Also, the GCC toolchain uses AT&T mnemonics, so they can make up their own rules.
