I'm writing an 8086 assembler that takes instructions and produce 8086 machine code. I use the "Intel 8086 User Manual" as a reference.
To make it clear I will explain the situation. Let's say I wanna assemble this instruction mov ax, bx
. I will look up the manual to find that when the operands of mov
are 2 16bit registers, the opcode for mov
is 0x89
and to specify the operands (the source and the destination), mov
, in this case, is followed by a ModRegRm byte that specifies the source and the destination, which, in this case, is 0xd8
. This byte in binary = 11011000
.
The Mod is 2 bits and the Reg, Rm are 3 bits each. so, Mod = 11, Reg = 011, Rm = 000. It's straight forward here, but there is something i don't understand, which is the addressing modes and the displacement.
Look at the table and the three following instructions and their machine code.
mov [bx+0x6], ax ;894706
mov [bx+0xbf],ax ;8987BF00
mov [bx+0xffff],ax ;8947FF
Am I wrong in assuming that the displacement length in each instruction is 8bit, 8bit, 16bit, respectively?
I think I'm right because it's obvious, 0x6
and 0xbf
are 1 byte and 0xffff
is two bytes.
The question is, why the MOD field in the second instruction is 10b or 0x02
instead of 01b or 0x01
? It should be 0x01
because the displacement is 8bit displacement, isn't it? And why the MOD is 0x01
in the third instruction even though the displacement is 16bit? and why the assembler ignored the rest of the displacement and captured only 1 byte?