How to use global variable in gcc inline assembly

I am trying to use an inline assembly like this for a global variable, but the compiler gives an error saying an undefined reference to saved_sp .

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

saved_sp is declared as static long saved_sp globally (for file). What mistake am I making here?

+6
source share
3 answers

If the failure "undefined refers 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 decided that saved_sp not used in your original file and therefore decided to completely exclude it from the compiled code that is passed to the assembler.

The compiler does not understand the assembly code inside the asm block; it just inserts it into the assembly code that it generates. Therefore, he does not know that the asm block refers to saved_sp , and if it never reads anything in the C code, he may decide that it is not used completely, especially if you have any optimization options.

You can tell gcc that saved_sp used so that it cannot see, and therefore does not allow it to throw it away by adding the used attribute (see the documentation for variable attributes , about halfway down the page), for example:

 static long __attribute__((used)) saved_sp; 

Here is a complete 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 the 32-bit Debian compression system with gcc 4.4.5, which is the closest I have to deal with; -m64 may well be unnecessary on your system.)

+6
source

As I pointed out in the comments, the following compilation (and generates the correct machine code) using gcc 4.4.4 in 64-bit Ubuntu:

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

Perhaps the problem may be completely different ( #include missing, so saved_sp is not really defined? Edit : now that you say this is static , I think it's not very likely.)

+1
source

It is preferable to use input and output parameters:

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

Often at the build stage, there may be some variables that are not characters (for example, stack variables or registers. In addition, you want to hide all memory to ensure that no stack variables are stored in the register after saved_sp stored in RSP.

+1
source

Source: https://habr.com/ru/post/905659/


All Articles