i386/x86_64 segment register issuses

H. J. Lu hjl@lucon.org
Mon Mar 28 19:34:00 GMT 2005


On Sun, Mar 27, 2005 at 06:55:44PM -0500, Ross Ridge wrote:
> > asm volatile("movl %%gs,%0" : "=g" (gsindex));
> >
> >The new assembler will disallow them since those instructions with
> >memory operand will only use the first 16bits. If the memory operand
> >is 16bit, you won't see any problems. But if the memory destinatin
> >is 32bit, the upper 16bits may have random values.
> 
> I'm pretty sure this isn't the case.  The memory operand can only
> be 16-bit, as any operand size prefix (or lack thereof) is ignored.
> It's only when the destination is a 32-bit register that the upper
> 16-bits are undefined.

In x86_64, for register destination, 16bit segment register is zero
extended to 32/64bits. In ia32, CPUs starting from Pentium Pro also
zero extend to 32bits.

> 
> I think gas should accept both "movl" and "movw" when moving between
> a segment register and a memory operand.  Regardless of which suffix
> is used the assembler should never emit an operand size prefix for
> the instruction.

Gas never emits operand size prefix for

	movw	%(eax),%ds

It isn't a problem. These are real codes:

                unsigned fsindex;
                asm volatile("movl %%fs,%0" : "=g" (fsindex));
                if (unlikely(fsindex | next->fsindex | prev->fs)) {
                        loadsegment(fs, next->fsindex);
                        if (fsindex)
                        prev->fs = 0;
                }

The current gas will accept this and. But if fsindex is ever a memory
operand,

                asm volatile("movl %%fs,%0" : "=g" (fsindex));

fsindex will have some random value in the upper 16bits. In fact, gas
will take

                asm volatile("movl %%fs,%0" : "=m" (fsindex));

I don't want gas to accept instructions which don't do what progamers
think they should do.



H.J.



More information about the Binutils mailing list