32-bit vs 16-bit default operand size

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Jane1991c
Posts: 22
Joined: Mon Oct 21, 2013 3:48 pm

32-bit vs 16-bit default operand size

Post by Jane1991c »

Hi,
I have a question about descriptor's attribute. I was reading http://wiki.osdev.org/Descriptors and found there such information:
bit 6 , D/B, Default operand size/Big, 0 for 16-bit segments; 1 for 32-bit segments
What does it means in practice ?

Does it mean that if I write in code:

var1 dw 0x0

then var1 is 32bit long when D=1 ? And what does db or dq in this case would mean ?

Or does it mean something else ? Or maybe it's somehow about opcodes ? Please for some explanation, thank you very much.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: 32-bit vs 16-bit default operand size

Post by Gigasoft »

It determines the encoding of instructions. The 66h prefix byte is used to distinguish between 16 and 32 bit forms of an instruction, and the 67h prefix selects between 16 and 32 bit addressing modes. The D bit specifies the behaviour when no prefix is present. The presence of a prefix indicates that the other size is used.
lihawl
Posts: 6
Joined: Fri Nov 29, 2013 7:08 pm

Re: 32-bit vs 16-bit default operand size

Post by lihawl »

No,default bit deosn't mean that.

Code: Select all

var1 dw 0x0
always means a double word (32 bits).
Gigasoft is right. The real meaning of default bit is how does a processor encode and decode a instruction.
For example. binaries

Code: Select all

8B 45 00
may have different meaning when default bit is not same.
if default bit equals 0, the code above means

Code: Select all

mov ax, word ptr [bp]
; Else defualt bit equals 1, it means

Code: Select all

mov eax, dword ptr  [ebp]
. A prefix (0x66 or 0x67) can reverse the default behavior(specified by default bit). I have a table that is copied from intel i386 manual.

Code: Select all

Segment Default D = ...  0  0  0  0  1  1  1  1
Operand-Size Prefix 66H  N  N  Y  Y  N  N  Y  Y
Address-Size Prefix 67H  N  Y  N  Y  N  Y  N  Y
Effective Operand Size  16 16 32 32 32 32 16 16
Effective Address Size  16 32 16 32 32 16 32 16
Y = Yes, this instruction prefix is present
N = No, this instruction prefix is not present
Note for beginner: `eax' is 32 bits operand; and `word ptr [eax]' is a 16 bits operand, but has 32 bits address size.
If your codes are in 32 bits mode(default bit equals 1): You hardly use 16 bits address size, so you almost don't use 0x67 prefix;But you should ofen access data which size is 16 bits, and in this case, you should use 0x66 prefix.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: 32-bit vs 16-bit default operand size

Post by Combuster »

lihawl wrote:No,default bit deosn't mean that.

Code: Select all

var1 dw 0x0
always means a double word (32 bits).
Nope. Regardless of the default bit you're always looking at a 16-bit word here.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
palk
Posts: 16
Joined: Mon Nov 15, 2010 8:30 pm

Re: 32-bit vs 16-bit default operand size

Post by palk »

lihawl wrote:The real meaning of default bit is how does a processor encode and decode a instruction.
That's what it means with respect to a code segment; it also has meaning for data segments and even more meaning for stack segments (sub-class of data segments).

For instance, you can be executing 32-bit code (CS descriptor's D=1), but if SS is loaded with a segment with D/B=0, then PUSH and POP will only modify ESP by 2 instead of the expected 4.
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: 32-bit vs 16-bit default operand size

Post by Antti »

palk wrote:For instance, you can be executing 32-bit code (CS descriptor's D=1), but if SS is loaded with a segment with D/B=0, then PUSH and POP will only modify ESP by 2 instead of the expected 4.
I think it does not make sense. It defines whether you use the ESP or SP. The 32-bit register or the 16-bit register, respectively. It is the operand size (code segment) that defines whether the stack is decremented (or incremented) 2 or 4 bytes. You can override it by adding the override prefix.
lihawl
Posts: 6
Joined: Fri Nov 29, 2013 7:08 pm

Re: 32-bit vs 16-bit default operand size

Post by lihawl »

Combuster wrote:
lihawl wrote:No,default bit deosn't mean that.

Code: Select all

var1 dw 0x0
always means a double word (32 bits).
Nope. Regardless of the default bit you're always looking at a 16-bit word here.
Yeah, you are right. `dw' means `define word' or `data word', not `double word'. I'm sorry for this stupid mistake.
rdos
Member
Member
Posts: 3306
Joined: Wed Oct 01, 2008 1:55 pm

Re: 32-bit vs 16-bit default operand size

Post by rdos »

Antti wrote:
palk wrote:For instance, you can be executing 32-bit code (CS descriptor's D=1), but if SS is loaded with a segment with D/B=0, then PUSH and POP will only modify ESP by 2 instead of the expected 4.
I think it does not make sense. It defines whether you use the ESP or SP. The 32-bit register or the 16-bit register, respectively. It is the operand size (code segment) that defines whether the stack is decremented (or incremented) 2 or 4 bytes. You can override it by adding the override prefix.
Absolutely. For instance, back when I still used 16-bit stack selectors in kernel, syscalls would leave the high part of ESP unmodified, and the stack would only use SP. This looked quite funny when called from a 32-bit flat application and the ESP in kernel had the high part of ESP from the application. I sometimes needed movzx esp,sp in order to fix this.
Post Reply