Why don't you just _test_ it? You'd see immediately what the difference
is:
int main()
{
unsigned long eax;
asm(".byte 0x8c,0xd8":"=a" (eax):"0"(-1));
printf("32-bit: %08lx\n", eax);
asm(".byte 0x66,0x8c,0xd8":"=a" (eax):"0"(-1));
printf("16-bit: %08lx\n", eax);
}
and it prints out
[torvalds@penguin torvalds]$ ./a.out
32-bit: 0000002b
16-bit: ffff002b
Notice? The 32-bit version (without the operand size override) changed all
32 bits, while the 16-bit version only changed the low 16 bits.
That is why gas _has_ to support:
movl %ds,%eax /* 32-bit version */
movw %ds,%ax /* 16-bit version */
> > Right. But it _has_ to be different from "movw %ds,%ax", and gas _has_ to
> > accept both forms (the 32-bit form for performance, the 16-bit form
> > because a programmer may require the high bits to not change).
>
> That is wrong since performance should be same for 16-bit and
> 32-bit forms. The only difference is "mov/movl %ds,%eax" will
> trach the high 16 bits of %eax.
Wrong. The version with a operand size prefix is SLOWER when you are
running on a Pentium. Look into the Pentium manuals: the operand size
prefix takes one cycle, and also makes the instruction unpairable.
Yes, intel doesn't say so explicitly in the instruction description part
of the manual. Which I've said before: you should not blindly look at
intel manuals.
And just to clear up: pushw %ds does change %esp by two, I just checked.
Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu