简体   繁体   English

如何在gcc内联汇编中使用全局变量

[英]How to use a global variable in gcc inline assembly

I am trying to use inline assembly like this, for a global variable, but the compiler gives an error by saying undefined reference to saved_sp . 我试图使用这样的内联汇编,作为全局变量,但编译器通过对saved_sp的未定义引用给出错误。

__asm__ __volatile__ (
        "movq saved_sp, %rsp\n\t" );

saved_sp is declared as static long saved_sp globally (for a file that is). saved_sp被声明为static long saved_sp (对于一个文件)。 What mistake am I doing here? 我在这做什么错?

If it fails with "undefined reference to `saved_sp' " (which is really a linker error, not a compiler error) when saved_sp is static , but works when it is not, then it seems likely that the compiler has decided that saved_sp is not used in your source file, and has therefore decided to omit it completely from the compiled code that is passed to the assembler. 如果它失败并且“未定义引用`saved_sp'”(这实际上是一个链接器错误,而不是编译器错误)当saved_spstatic ,但是当它不是时工作,那么编译器似乎已经确定saved_sp不是在源文件中使用,因此决定从传递给汇编程序的已编译代码中完全省略它。

The compiler does not understand the assembly code inside the asm block; 编译器不理解asm块内的asm代码; it just pastes it into the assembly code that it generates. 它只是将其粘贴到它生成的汇编代码中。 So it does not know that the asm block references saved_sp , and if nothing else in the C code ever reads from it, it is at liberty to decide that it is completely unused - particularly if you have any optimisation options enabled. 因此,它不知道asm块引用saved_sp ,如果C代码中没有其他内容可以从中读取,则可以自由决定它是否完全未使用 - 特别是如果您启用了任何优化选项。

You can tell gcc that saved_sp is used by something that it can't see, and therefore prevent it from choosing to throw it away, by adding the used attribute (see the documentation of variable attributes , about half-way down the page), eg: 你可以告诉gccsaved_sp被它看不到的东西使用,因此通过添加used属性阻止它选择扔掉它(参见变量属性文档 ,大约在页面的中间),例如:

static long __attribute__((used)) saved_sp;

Here's a fully worked example: 这是一个完整的例子:

$ 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
$ 

(This is from a 32-bit Debian squeeze system with gcc 4.4.5, which is the closest thing I have to hand; -m64 may well be unnecessary on your system.) (这是来自32位Debian挤压系统,带有gcc 4.4.5,这是我最接近的东西; -m64在您的系统上可能是不必要的。)

Preferably you would use input and output parameters: 您最好使用输入和输出参数:

__asm__ __volatile__ ( 
    "movq %0, %%rsp\n\t"
    : : "r"(saved_sp) : "memory"
);

Often there can be some variables that are not symbols at all at the assembling stage (for example stack variables, or registers. Also, you'd want to clobber the whole memory, to ensure that no stack variables are kept in register after the saved_sp is stored in RSP. 在组装阶段通常可能存在一些根本不是符号的变量(例如堆栈变量或寄存器。另外,你想要破坏整个内存,以确保在saved_sp之后没有堆栈变量保存在寄存器中存储在RSP中。

As I indicated in the comments, the following compiles (and generates the correct machine code) using gcc 4.4.4 on 64-bit Ubuntu: 正如我在评论中指出的那样,以下在64位Ubuntu上使用gcc 4.4.4编译(并生成正确的机器代码):

long saved_sp;

int main() {
  __asm__ __volatile__ (
        "movq saved_sp, %rsp\n\t" );
}

Perhaps the issue could be something else entirely (a missing #include so that saved_sp is actually not defined? edit : now that you say it's static , I guess that's not very likely.) 也许这个问题可能完全是另一回事(缺少#include ,以至于saved_sp实际上没有被定义? 编辑 :现在你说它是static ,我想这不太可能。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM