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"
);
The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces.
In computer programming, an inline assembler is a feature of some compilers that allows low-level code written in assembly language to be embedded within a program, among code that otherwise has been compiled from a higher-level language such as C or Ada.
The asm keyword allows you to embed assembler instructions within C code. GCC provides two forms of inline asm statements. A basic asm statement is one with no operands (see Basic Asm), while an extended asm statement (see Extended Asm) includes one or more operands.
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.
Your only option is to use Intel syntax. GCC, of course, can generate insn like mov off(base, index, scale)
, but does this on the level of whole MEM
RTL expressions, i.e. not having offset, base, etc like individual operands.
So, Intel syntax, compile the following with gcc -c -masm=intel x.c
:
#include <stddef.h>
struct s
{
int a, b;
};
int foo (struct s *s, int i)
{
int r;
asm (
"mov %[r], dword ptr [%[s]+%[index]*8 + %[displ]] "
: [r] "=r" (r)
: [s] "r" (s) , [index] "r" (i),
[displ] "e" (offsetof(struct s, b))
:
);
return r;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With