lkml.org 
[lkml]   [1998]   [Mar]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH] APM support doesn't compile with binutils 2.8.1.0.24


On Wed, 25 Mar 1998, Bernhard Rosenkraenzer wrote:
>
> According to the binutils people, it's related to bogus asm in apm_bios.c
> - the patch I've attached fixes it.

Are the binutils people aware that the size prefix _does_ make a
difference for segment loads?

If you do a 16-bit "mov seg -> reg", the operation will write only the low
16 bits, while if you do a 32-bit version it will actually write all 32
bits (high bits zero, I do believe).

(Just to confuse matters: if the destination is memory, it seems to be
always written 16 bits at a time regardless of the size of the operand.
Don't you all love Intel?)

Anyway, this does mean that people can quite _deliberately_ need both the
16- and 32-bit versions, and gas _should_ accept a "w" or "l" at the
instruction to imply which one is needed.

The old gas bug was that it defaulted to 16-bit mode which is slower and
bigger (and is also strange, considering that gas always otherwise
defaults to 32-bit mode when not told otherwise). But the new gas
behaviour is equally buggy in that it appears to not support the 16-bit
mode at all, and even complains when explicitly given a (legal) size.

The "b" case (8-bit) is illegal and should not be allowed (which was my
original complaint about the patch that Ingo posted).

In short:

push %ds : legal, should default to 32-bit mode, no override
pushl %ds : legal, 32-bit, no override
pushw %ds : legal, 16-bit, operand size override
pushb %ds : illegal

mov %ds,%eax : legal, should default to 32-bit mode, no override
mov %ds,%ax : if gas notices that "%ax" is 16-bit it would be great.
movw %ds,%ax : 16-bit, operand size override REQUIRED
movl %ds,%eax : 32-bit, no override

When moving to memory (pushw and movw to memory) the 16-bit override _may_
be optimized away, but as explained above it definitely may NOT be
optimized away when moving to a register because the behaviour is very
different (I don't know whether the segment checks are for 16- or 32-bit
entities, though, so maybe even the mov-to-memory case is different).

When moving _to_ a segment register there really isn't any difference
between a 16-bit and a 32-bit operand size (there is no zero-extend
semantics for moving to segment registers), but even then the assembler
should probably allow specifying an override, and should _definitely_
allow specifying a size (that might be ignored) in order to have the same
syntax as moving the other way:

pop %ds : default to 32-bit, no override
popl %ds : 32-bit, no override
popw %ds : 16-bit (but maybe the override can be optimized away)

mov %eax,%ds : legal, should default to 32-bit mode, no override
movl %eax,%ds : legal, no override
movw %ax,%ds : 16-bit (but maybe the override can be optimized away)

So I think the APM bios access code is actually correct in specifying a
"l" on the push/pop operations.

Linus


-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu

\
 
 \ /
  Last update: 2005-03-22 13:41    [W:1.137 / U:0.016 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site