how can I send the offset of a C struct to en assembly code ?
For example
In my C code I have
typedef struct
{
unsigned int a;
unsigned int b;
} CMyStruct;
I send to an ASM function a pointer of a CMyStruct structure
Let suppose that my pointer is into R0
To access to a and b attribute I need to do that.
ldr r1, [r0, #0] // read a
ldr r2, [r0, #4] // read b
Is there anyway to not specify #0 and #4 as contant value ?
Something like
ldr r1, [r0, CMyStruct.a] // read a
ldr r2, [r0, CMyStruct.b] // read b
Thank's
Etienne
There is a way, actually. The solution is contains a little bit of magic, but it's works. It's just works.
in c file:
#define DEFINE(sym, val) asm volatile("\n-> " #sym " %0 " #val "\n" : : "i" (val))
#define OFFSETOF(s, m) \
DEFINE(offsetof_##s##_##m, offsetof(s, m));
#define SIZEOF(s) \
DEFINE(sizeof_##s, sizeof(s));
void foo()
{
OFFSETOF(KERNEL, error);
OFFSETOF(KERNEL, pool);
SIZEOF(KERNEL);
}
in Makefile:
asm_defines.h: asm_defines.c
$(GCC) $(FLAGS_CC) -S $< -o - | awk '($$1 == "->") { print "#define " $$2 " " $$3 }' > $(BUILD_DIR)/$@
Finally you will got asm_defines.h, which you can include in your .S file.
#define offsetof_KERNEL_error #16
#define offsetof_KERNEL_pool #4
#define sizeof_KERNEL #120
You could use GCC extended inline assembly code and use the offsetof
macro.
How about something like this:
#include <stddef.h> /* offsetof */
struct CMyStruct
{
unsigned int a;
unsigned int b;
};
int main()
{
asm("ldr r1, [r0, %[OffsetOfA]] \n\t"
"ldr r2, [r0, %[OffsetOfB]] \n\t"
: /* no outputs */
: [OffsetOfA] "i" (offsetof(struct CMyStruct, a)), [OffsetOfB] "i" (offsetof(struct CMyStruct, b)));
}
Obviously that's not quite right, since you don't want to hard code r0/r1/r2, but it should point you in the right direction.