Page 1 of 1
32-bit vs 16-bit default operand size
Posted: Wed Jan 08, 2014 3:59 pm
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.
Re: 32-bit vs 16-bit default operand size
Posted: Wed Jan 08, 2014 4:25 pm
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.
Re: 32-bit vs 16-bit default operand size
Posted: Sat Jan 11, 2014 2:55 pm
by lihawl
No,default bit deosn't mean that.
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
may have different meaning when default bit is not same.
if default bit equals 0, the code above means
; Else defualt bit equals 1, it means
. 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.
Re: 32-bit vs 16-bit default operand size
Posted: Sat Jan 11, 2014 3:13 pm
by Combuster
lihawl wrote:No,default bit deosn't mean that.
always means a double word (32 bits).
Nope. Regardless of the default bit you're always looking at a 16-bit word here.
Re: 32-bit vs 16-bit default operand size
Posted: Sat Jan 11, 2014 3:21 pm
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.
Re: 32-bit vs 16-bit default operand size
Posted: Sat Jan 11, 2014 4:07 pm
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.
Re: 32-bit vs 16-bit default operand size
Posted: Mon Jan 13, 2014 10:12 pm
by lihawl
Combuster wrote:lihawl wrote:No,default bit deosn't mean that.
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.
Re: 32-bit vs 16-bit default operand size
Posted: Tue Jan 14, 2014 5:06 am
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.