且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何使用GCC内联汇编的全局变量

更新时间:2022-06-02 03:27:33

如果它失败未定义参考`saved_sp'(这是一个真正的的链接的错误,而不是一个编译器错误)时 saved_sp 静态,但工作时,它不是,那么它很可能是编译器已经决定 saved_sp 不是在源文件中使用,因此决定从传递给汇编编译code完全忽略它。

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.

编译器不明白 ASM 块内的组装code;它只是它粘贴到装配code,它生成。所以它不知道 ASM 块参照 saved_sp ,如果不出意外在C code以往从中读取,它可以***地决定它是完全未使用 - 特别是如果你有任何启用优化选项

The compiler does not understand the assembly code inside the asm block; 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.

您可以告诉 GCC saved_sp 所使用的东西,它看不见,所以$ P从$选择把它扔掉,加入使用属性(请参阅变量的文档属性,大约中途下页),例如:

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), e.g.:

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
$ 

(这是一个32位的Debian挤压系统使用GCC 4.4.5,这是我不得不手工最接近; -m64 可能是不必要的您的系统。)

(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.)