Messages in this thread | | | Date | Tue, 25 Jul 2000 06:08:48 +1000 | From | Andrew Morton <> | Subject | Re: asm in C slightly OT |
| |
> 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/
| |