【发布时间】:2012-11-29 08:57:24
【问题描述】:
我有一个包含内联程序集的内联函数定义。我想选择 根据参数是否存在不同的内联汇编实现 在构建时是否已知。
我的问题是如何在 C 代码或内联汇编中询问 address 值是否在构建时是已知的,因此是否适合作为立即值。如果您正在考虑 __builtin_constant_p - 请提前阅读。
这里有一段代码说明了我的意图:。我正在尝试找到一种实现“is_immediate”的方法。
static char arr[5];
void __attribute__((always_inline)) do_something(char * buf)
{
if(is_immediate(buf) {
// Argument is constant, can use immediate form
asm volatile ("insn1 %0" : : "i"(buf));
} else {
// Argument is computed at runtime, use a register
unsigned long tmp = (unsigned long)buf + 1;
asm volatile("insn2 %0" : : "r"(tmp));
}
int main(void)
{
do_something(&arr);
}
乍一看,__builtin_constant_p() 似乎正是所需的魔法,但它不起作用。
原因是不起作用的,虽然在链接器将数组放入内存并为其选择地址之后,数组的地址将是已知的(因此它确实符合内联汇编的直接约束),在链接之前的编译时间不知道。
所以,我正在寻找一种询问方式 - “这个变量是否适合作为直接值?”而不是“这是一个常量表达式吗?”。
【问题讨论】:
-
类型不匹配。为什么参数是
char *,而不是char (*)[5]? -
@KerrekSB 请注意,我将 arr 的地址作为参数发送,而不是 arr 本身。
-
@gby 这就是我认为的重点。传递
arr就像传递&arr[0]=char*因为数组对象在左值到右值的转换过程中被转换。 OTOH&arr已经是char(*)[5]类型的右值,因为arr是char[5]类型。 -
tl;dr 当您将数组用作右值时,数组会衰减为指向第一个成员的指针,因此在传递给函数或执行
arr[i]或将其分配给指针时,但是不是在做&arr时,因为&适用于左值。 -
@Kos 我会争论,但我不明白它与我的问题有什么关系 - 无论我使用 arr 还是 &arr,结果都是一样的,所以我现在就闭嘴。
标签: c gcc ld gnu-assembler