• Please review our updated Terms and Rules here

80386 D-bit

kerravon

Experienced Member
Joined
Oct 31, 2021
Messages
137
PM32 of the 80386 allows you to set the D-bit on a segment to say it is 16-bit.

There are some op codes that have changed behavior between RM16 and PM32. I can probably find an example if required.

If you set the D-bit to 16-bit, do you get the RM16 behavior of those opcodes, or the new PM32 behavior?

Thanks.
 
Wouldn't it be PM16 behavior since the descriptor of 16-bits would only apply in code running in 286 protected mode? Real mode and V86 mode don't have descriptors.
 
Wouldn't it be PM16 behavior since the descriptor of 16-bits would only apply in code running in 286 protected mode? Real mode and V86 mode don't have descriptors.

Ok, yes, I should have said PM16, not RM16.

Here is an example I was given of the same opcodes being used for quite different things:

;32-bit code
00000028 89FB mov ebx,edi
0000002A 8B4720 mov eax,[edi+32]

;16-bit code
00000028 89FB mov bx,di
0000002A 8B4720 mov ax,[bx+0x20]


The D-bit on an 80386 set to 16-bit would be expected to get the "mov bx, di" to take effect, as that is exactly what it is supposed to do - override the size.

But will it ensure that an opcode that (in this case) references edi, instead references bx?
 
Yes, the 16-bit addressing modes are different from those in 32-bit mode. Intel originally chose to only allow certain combinations of base+index, so that all of them could be encoded in 3 bits - and this was apparently more important than allowing any register to be used. So base must be BX or BP (or null), and index must be SI/DI/null.

In 32-bit mode, the short encoding is used to select any single 32-bit register(*), and more complex modes require another 'SIB' byte (scale, index, base).

There are two prefixes that override 16-/32-bit mode: one for operand size (66H) and another for addressing (67H).

So in 16-bit code, it will be interpreted like this:

Code:
8B 47 20        mov ax,[bx+32]
66 8B 47 20     mov eax,[bx+32]
67 8B 47 20     mov ax,[edi+32]
66 67 8B 47 20  mov eax,[edi+32]

And in 32-bit code, the effect of the prefixes is simply reversed.

(*) except ESP, though it can be used as a base with no index when the SIB byte is present. The assembler should take care of encoding details like that.
 
Last edited:
Back
Top