![](/img/trans.png)
[英]How to use global variable in Inline Assembly in Greenhills Compiler?
[英]How to use a global variable in gcc inline assembly
我试图使用这样的内联汇编,作为全局变量,但编译器通过对saved_sp的未定义引用给出错误。
__asm__ __volatile__ (
"movq saved_sp, %rsp\n\t" );
saved_sp被声明为static long saved_sp
(对于一个文件)。 我在这做什么错?
如果它失败并且“未定义引用`saved_sp'”(这实际上是一个链接器错误,而不是编译器错误)当saved_sp
是static
,但是当它不是时工作,那么编译器似乎已经确定saved_sp
不是在源文件中使用,因此决定从传递给汇编程序的已编译代码中完全省略它。
编译器不理解asm
块内的asm
代码; 它只是将其粘贴到它生成的汇编代码中。 因此,它不知道asm
块引用saved_sp
,如果C代码中没有其他内容可以从中读取,则可以自由决定它是否完全未使用 - 特别是如果您启用了任何优化选项。
你可以告诉gcc
, saved_sp
被它看不到的东西使用,因此通过添加used
属性阻止它选择扔掉它(参见变量属性的文档 ,大约在页面的中间),例如:
static long __attribute__((used)) saved_sp;
这是一个完整的例子:
$ cat test.c
#ifdef FIXED
static long __attribute__((used)) saved_sp;
#else
static long saved_sp;
#endif
int main(void)
{
__asm__ __volatile__ (
"movq saved_sp, %rsp\n\t" );
}
$ gcc -m64 -o test test.c
$ gcc -m64 -O1 -o test test.c
/tmp/ccATLdiQ.o: In function `main':
test.c:(.text+0x4): undefined reference to `saved_sp'
collect2: ld returned 1 exit status
$ gcc -m64 -DFIXED -O1 -o test test.c
$
(这是来自32位Debian挤压系统,带有gcc 4.4.5,这是我最接近的东西; -m64
在您的系统上可能是不必要的。)
您最好使用输入和输出参数:
__asm__ __volatile__ (
"movq %0, %%rsp\n\t"
: : "r"(saved_sp) : "memory"
);
在组装阶段通常可能存在一些根本不是符号的变量(例如堆栈变量或寄存器。另外,你想要破坏整个内存,以确保在saved_sp
之后没有堆栈变量保存在寄存器中存储在RSP中。
正如我在评论中指出的那样,以下在64位Ubuntu上使用gcc 4.4.4
编译(并生成正确的机器代码):
long saved_sp;
int main() {
__asm__ __volatile__ (
"movq saved_sp, %rsp\n\t" );
}
也许这个问题可能完全是另一回事(缺少#include
,以至于saved_sp
实际上没有被定义? 编辑 :现在你说它是static
,我想这不太可能。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.