内联汇编操作数约束

Posted

技术标签:

【中文标题】内联汇编操作数约束【英文标题】:inline assembly operand constraints 【发布时间】:2015-02-18 18:07:41 【问题描述】:

关于我想要理解的一段代码,我有几个问题。我读过the manual here。但它似乎并没有解释或回答这里使用的所有技巧。

代码如下:

#define SAMPLE_OFFSET1 0
#define SAMPLE_OFFSET2 100
#define SAMPLE_OFFSET1 1000
#define STRINGIFY(s) #s

struct data 
    int m1;
    int m2;
    const uint *m3;
    const uint *m4;
;

#define assembly_function(param1, ... param15) \
... body \
... body \
... body \
... body

void testFunction (data* c, uint *const sample) 
int bat, tmp;
    __asm__ volatile(
        assembly_function("%0", "%q0", "(%4)", "%1", "%w1",
                             "%2", "%q2", "%3", "%b3",
                             "%c6(%5)", "%c7(%5)",
                             STRINGIFY(SAMPLE_OFFSET1),
                             STRINGIFY(SAMPLE_OFFSET2),
                             STRINGIFY(SAMPLE_OFFSET3),
                             "%8")
        : "=&r"(bat), "=&r"(c->m1), "=&r"(c->m2), "=&q"(tmp)
        : "r"(sample), "r"(c),
          "i"(offsetof(data, m3)),
          "i"(offsetof(data, m4)),
          "1"(c->m1), "2"(c->m2)
        : "%rcx", "memory"
    );

我对以下一些约束/选项的用法有很大的猜测。但我觉得最好从其他人那里确认(或获取一些详细手册的链接)。

“%c6(%5)”和“%c7(%5)”中的%c “%q0”和“%q2”中的%q, “%b3”中的%b %w in "%w1" “(%4)”中的括号 “i”表示两个输入参数。 “1”和“2”表示两个输入参数。

感谢您的帮助。

【问题讨论】:

远离诡计。坚持简单明了。无论如何,事情都会变得很棘手。 【参考方案1】:

%c 强制输出为常量地址,在这里它用于摆脱通常在 at&t 语法模式下为立即数发出的 $i 约束暗示)。

%b%w%l%q 是大小覆盖修饰符,它们为操作数强制使用适当大小的寄存器(即字节、字、长整数或四字节)。

括号只是您日常 at&t 风格有效地址语法的一部分。

i 是立即整数操作数(具有常量值)。

"1""2" 是匹配约束,即将它们放置在与指示的其他操作数相同的位置。

【讨论】:

感谢您的评论。关于 %c,理解 "%c6(%5)" == %5 和 %6 的值的总和并将其用作内存中的常量地址是否正确,我们只能从中读取但不能写入? 不,地址是常量而不是值。这是foo* const 而不是const foo*

以上是关于内联汇编操作数约束的主要内容,如果未能解决你的问题,请参考以下文章

扩展内联汇编基础

内联汇编约束修饰符 = 和 +

内联汇编中的 sse 约束不起作用

GCC内联汇编常见陷阱

高级CGNU C/C++ 内联汇编——进阶——约束详解

操作系统学习之GCC内联汇编