3

I'm trying to use a small amount of AT&T style inline assembly in C and GCC by reading an article on CodeProject here. The main reason I wish to do this is to find the old value of the EIP register to be able to have a reliable address of instructions in my code. I have written a simple example program to demonstrate my understanding of this concept thus far :

#include <stdio.h>
#include <stdlib.h>

int mainReturnAddress = 0;

int main()
{
    asm volatile (
         "popl %%eax;"
         "pushl %%eax;"
         "movl %%eax, %0;"
         : "=r" ( mainReturnAddress )
       );

    printf( "Address : %d\n",  mainReturnAddress );
    return 0;
}

The purpose of this particular example is to pop 4 bytes from the top of the stack representing the 32 bit return address saved from the EIP register, and then to push it back on the stack. Afterwards, I store it in the global mainReturnAddress variable. Finally, I print the value stored in mainReturnAddress.

The output from I recieve from this code 4200560.

Does this code achieve the purpose aforementioned, and is this is cross processor on the Windows platform 32-bit?

rkhb
  • 14,159
  • 7
  • 32
  • 60
user3476738
  • 176
  • 2
  • 12
  • 1
    What goes on the stack is very implementation specific. If you have local stack variables, they'll be on the stack as well, so popping the top of the stack is not guaranteed to get you what you want. But why do you need the return address? If you just want to get a "reliable" address of any instruction, you can just do `int mainAddress = (int) main;`, that is just get the address of `main` itself. Some people like to do `(int)&main` but that is not necessary. – Mark Lakata May 22 '14 at 23:42
  • 4
    In addition to the good points Mark and Carl made, this asm modifies eax without telling gcc you are doing so. This is a great way to introduce very weird bugs. A better solution would be to change pushl/popl %%eax to use %0 and remove the movl. Oh, and treating pointers as ints is a bad idea if you ever intend to support 64bit. Bad habit in any case. – David Wohlferd May 23 '14 at 01:06

1 Answers1

5

In GCC, you should use __builtin_return_address rather then trying to use inline assembly.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469