Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 351 Vote(s) - 3.46 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to use a global variable in gcc inline assembly

#1
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**.

__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?
Reply

#2
As I indicated in the comments, the following compiles (and generates the correct machine code) using `gcc 4.4.4` on 64-bit Ubuntu:

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

#3
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.

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.

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](

[To see links please register here]

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

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

#4
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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through