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). What mistake am I doing here?
saved_sp被声明为static long saved_sp global(对于一个文件)。我在这做什么错?
3 个解决方案
#1
6
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_sp是静态的,但是当它不是时工作,那么编译器似乎已经确定saved_sp不是在源文件中使用,因此决定从传递给汇编程序的已编译代码中完全省略它。
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.
编译器不理解asm块中的汇编代码;它只是将其粘贴到它生成的汇编代码中。因此,它不知道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), e.g.:
你可以告诉gcc,saved_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.)
(这是来自一个带有gcc 4.4.5的32位Debian挤压系统,这是我最接近的东西; -m64在您的系统上可能是不必要的。)
#2
1
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以便save_sp实际上没有被定义?编辑:现在你说它是静态的,我想这不太可能。)
#3
1
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中。
#1
6
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_sp是静态的,但是当它不是时工作,那么编译器似乎已经确定saved_sp不是在源文件中使用,因此决定从传递给汇编程序的已编译代码中完全省略它。
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.
编译器不理解asm块中的汇编代码;它只是将其粘贴到它生成的汇编代码中。因此,它不知道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), e.g.:
你可以告诉gcc,saved_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.)
(这是来自一个带有gcc 4.4.5的32位Debian挤压系统,这是我最接近的东西; -m64在您的系统上可能是不必要的。)
#2
1
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以便save_sp实际上没有被定义?编辑:现在你说它是静态的,我想这不太可能。)
#3
1
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中。