8

我正在尝试以 GCC 样式扩展 asm(x86-64 目标)编写一小段代码,并且在编码结构偏移量时遇到问题。

我有一个struct swith a member size_t a[],一个指向这种结构的指针和一个索引,它们都是在 asm 块中生成的。

现在我需要在 asm 中处理该元素

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

如何编码displ到 asm 块中?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 邮件列表也提到了这个;那里的关键字是“输出替换”。
stackoverflow 发布的%c 在 GCC 内联汇编代码中是什么意思?也有关于%c特别的解释。

于 2012-11-23T09:51:04.307 回答
2

您唯一的选择是使用 Intel 语法。当然,GCC 可以生成 insn like mov off(base, index, scale),但是在整个MEMRTL 表达式的级别上执行此操作,即没有偏移量、基数等,例如单个操作数。

因此,英特尔语法,编译以下内容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 回答