GCC extended asm, struct element offset encoding

c, gcc, i386, inline-assembly

Solution

It actually is possible, using the `%c...` operand modifier:

#include <stddef.h>
#include <stdint.h>

struct s
{
  int a, b;
};

int foo (struct s *s, int i)
{
  int r;
  asm (
       "movl %c[displ](%[s],%[index],8), %[r]\n\t"
       : [r] "=r" (r)
       : [s] "r" (s) , [index] "r" ((uintptr_t)i),
         [displ] "e" (offsetof(struct s, b))
       :
       );

  return r;
}

Thanks where thanks is due - found that here. There's a gcc mailing list posting referring to this as well; the keywords there are "output substitution". The stackoverflow posting What does %c mean in GCC inline assembly code? also has an explanation about `%c` in particular.

Problem

I am trying to write a small piece of my code in GCC style extended asm (x86-64 target) and am having trouble encoding struct offsets. I have a `struct s` with a member `size_t a[]`, a pointer to such a struct and an index both of which are generated within the asm block. Now I need to address that element in asm ``` asm ( "mov %[displ](%[s], %[index], 8), %%rbx" : [s] "+r" (s) , [index] "+r" (i) : "memory", "cc", "rax", "rbx" ); ``` How can I encode `displ` into the asm block? Passing `offsetof(struct s, a)` as an immediate prefixes it with `$` and generates invalid assembly. ``` asm ( "mov %[displ](%[s], %[index], 8), %%rbx" : [s] "+r" (s) , [index] "+r" (i) : [displ] "i" (offsetof(struct s, a)) : "memory", "cc", "rax", "rbx" ); ```

Original source

Related problems