Re: asm in C slightly OT

From: Andrew Morton (andrewm@uow.edu.au)
Date: Mon Jul 24 2000 - 15:08:48 EST


> I can live without the register allocation. Its the need to track
> offsets that is bugging me. The same problem appears in
> ...i386/kernel/entry.S. Several answers to this problem have appeared
> from time to time, but all just try to cover up a rather nasty hole in
> the C/asm combination. What is needed is a construct that will allow
> you to evaluate something like (int)&((struct foo *)0)->bar and stuff
> it into an asm statment.

But for some `gas` capriciousness, this would work:

struct thing
{
        int a;
        int b;
        int stuff;
};

#define OFFSETOF(strct, elem) ((long)&(((struct strct *)0)->elem))

dummy()
{
        asm(".equ STUFF_OFFSET,%0"::"i" (OFFSETOF(thing, stuff)));
}

asm("movl STUFF_OFFSET(%eax),%ecx");

main()
{}

It emits, effectively:

        .equ STUFF_OFFSET,$8
        movl STUFF_OFFSET(%eax),%ecx

Which is, I believe, exactly what you want.

The problem is that gas thinks that `$8' in a pseudo-op is a
label, whereas `$8' in a machine insn is a constant!

I hesitate to say "stupid gas" because when you do that
you are then told that there's a good reason for the behaviour.

But I'll risk it: Stupid gas.

Perhaps you can trick gcc into not emitting the `$'.
Perhaps you can trick gas into accepting the `$'.
Perhaps you can complain to your assembler vendor.
Perhaps you can run `sed' across the .s file prior to assembly:

Change ".equ STUFF_OFFSET,%0" to ".equ STUFF_OFFSET,DELETE_ME%0"
and then use `sed' to remove all occurrences of `DELETE_ME$'.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jul 31 2000 - 21:00:17 EST