8

GCCスタイルの拡張asm(x86-64ターゲット)でコードの一部を書き込もうとしていますが、構造体オフセットのエンコードに問題があります。

にはstruct s、メンバーsize_t a[]、そのような構造体へのポインター、およびインデックスがあり、どちらもasmブロック内で生成されます。

今、私はasmでその要素に対処する必要があります

asm (
    "mov %[displ](%[s], %[index], 8), %%rbx"
    : [s] "+r" (s)
    , [index] "+r" (i)
    : "memory", "cc", "rax", "rbx"
);

displasmブロックにエンコードするにはどうすればよいですか?即時として渡すoffsetof(struct s, a)と、プレフィックスとして$無効なアセンブリが生成されます。

asm (
    "mov %[displ](%[s], %[index], 8), %%rbx"
    : [s] "+r" (s)
    , [index] "+r" (i)
    : [displ] "i" (offsetof(struct s, a))
    : "memory", "cc", "rax", "rbx"
);
4

2 に答える 2

11

オペランド修飾子を使用すると、実際に可能です。%c...

#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;
}

感謝が必要なところに感謝します-ここでそれを見つけました。これを参照するgccメーリングリストの投稿もあります。キーワードは「出力置換」です。
スタックオーバーフローの投稿GCCインラインアセンブリコードで%cはどういう意味ですか?%c特にについての説明もあります。

于 2012-11-23T09:51:04.307 に答える
2

唯一のオプションは、Intel構文を使用することです。もちろん、GCCはのようなinsnを生成できますがmov off(base, index, scale)、これはRTL式全体のレベルで実行されMEMます。つまり、個々のオペランドのようにオフセットやベースなどがありません。

したがって、Intel構文では、次のようにコンパイルします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;
}
于 2012-11-20T16:24:15.597 に答える