2

I want get the values in EAX/EBX/ESP/EIP etc. and save them in C variables. For example:

int cEax;
asm("mov cEax,%eax"); ...
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
user3808900
  • 63
  • 1
  • 4
  • 1
    You need to provide more details: What compiler are you using? 32bit or 64bit? And most important, what are you actually trying to accomplish? Just saying "read a register" doesn't mean much. Looking at your "example," the variable cEax might currently be in the eax register. Making your asm statement meaningless. – David Wohlferd Jul 06 '14 at 05:10
  • i want get registers and flags with 32bit gcc. i want print registers(esp,eip,eax,...) – user3808900 Jul 06 '14 at 05:21
  • asm("movl $0x12, %ecx"); asm("":"=c"(ecx)); – user3808900 Jul 06 '14 at 05:24
  • @user3808900 if you've found out the correct technique you need to accomplish this, why not share your knowledge by writing it up and posting it as a self-answer? That's allowed and welcome here. – Alex Celeste Jul 06 '14 at 05:53
  • I want to show the value of eip. this is my problem. – user3808900 Jul 06 '14 at 06:11
  • instruction pointer when doing what? it changes all the time with execution of instructions – Deleted User Jul 06 '14 at 06:44
  • yes,i know. i need values of esp/ebp/... and other registers.(Similar to a debugger). i want to show this values in our OS: http://kosaros.blog.ir – user3808900 Jul 06 '14 at 06:55

1 Answers1

3

You can use this

register int eax asm("eax");
register int eax asm("ebx");
register int eax asm("esp");
//...
int cEax = eax;
int cEbx = ebx;
int cEsp = esp;
//...

You can also work with those registers in an expression just as any other variables or just use that register's value directly without assigning to another variable.

It's more tricky to get eip without inline assembly but in gcc you can get it with __builtin_return_address or the label as values extension.

void* getEIP()
{
    return __builtin_return_address(0);
}

void *currentInstruction = getEIP();
currentAddr: void *nextInstruction = &&currentAddr;

If you want inline assembly you can use the way in this page

Community
  • 1
  • 1
phuclv
  • 37,963
  • 15
  • 156
  • 475
  • in x86_64 it's far more easier to get the instruction address with RIP relative addressing – phuclv Feb 28 '16 at 14:47
  • Hi @LưuVĩnhPhúc, I've compiled the code but getting this error. `user@linux:~/c$ gcc eip2.c eip2.c:9:28: error: initializer element is not constant void *currentInstruction = getEIP(); ^~~~~~ eip2.c:10:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘:’ token currentAddr: void *nextInstruction = &&currentAddr; ^ user@linux:~/c$ ` –  May 23 '18 at 04:11
  • 2
    Your use of `register` `asm` here only works because of luck more or less. What you are doing isn't supported by GCC's [Local Register Variables](https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html) . The only point where the register is guaranteed to be used is as an input,,output, input/output operand of an extended inline assembly template. Per the docs _The only supported use for this feature is to specify registers for input and output operands when calling Extended asm (see Extended Asm)_ – Michael Petch May 23 '18 at 05:50
  • See also [How to print EIP address in C?](https://stackoverflow.com/q/50471237) for some other ways to get a code address, including x86-64 inline asm with a RIP-relative LEA. Letting the compiler do it for you with a GNU C label-as-variable seems just as good, unless you want to use dummy inputs or outputs to order it wrt. generated code for other parts of the function. – Peter Cordes Oct 25 '22 at 21:51