Re: asm in C slightly OT

From: George Anzinger (george@pioneer.net)
Date: Mon Jul 24 2000 - 17:25:24 EST


HPA asked why asm outside of a function? If you go back to the original
post, that was real code from the kernel. It is interrupt handling code
and is, indeed outside of a function, after all the interrupts need to
start somewhere.

Andrew Morton wrote:
>
> > 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)));
> }
Or maybe: asm(".equ STUFF_OFFSET,%0"::"i" (things.stuff))); where we
have bound: struct thing things;

This is close to what I did. If you look at the asm code produced when
you wrap the asm with a dummy() you find that there are a few
instructions before and after the asm. In the case in point this did
not matter as the entry is by a jmp and the last instruction jmped out.
In fact, by doing the wrap I was able to:

dummy()
{
        asm(.....);
        ++things.stuff;
        asm(....);
}
Careful inspection proved that this was as good as I could do in asm and
keeps everything tracking the structures. Cost: about 4 wasted
instructions.

Thanks to all who responded.
George
>
> 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/

-
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:18 EST