GDB: Assembly instruction calculation

assemblycgdb

I'm new to assembly. Is there a way to execute a calculation in GDB apart from the actual code being debugged? For example, I'm stepping through the following using Linux IA-32 assembly (AT&T syntax):

   ;$esi is 0xbffff0a8 which refers to 1 after this command. $eax is 2
   0x08048cd5 <+42>:    lea    -0x20(%ebp),%esi

   ;$eax=ebx=2 after this instruction
   0x08048cd8 <+45>:    mov    %ebx,%eax 

   ;$eax equals 2 after this instruction               
   0x08048cda <+47>:    add    -0x4(%esi,%ebx,4),%eax

I'm just not seeing how $eax ends up at 2. Can I assue an instruction like: -0x4(%esi,%ebx,4) in gdb and analyze the result?

As I understand it, $ebx is multiplied by 4 to yield 8. That is added to $esi to give 9. Then -4 is subtracted to give 5. Then five is added to $eax which was 2 to yield 7. Instead $eax is 2.

Best Answer

You can evaluate expressions using registers, if that's what you're asking.

gdb's print command is your friend.

Basically you can query the registers by prepending a dollar sign, e.g.

print $ecx

or use them in expressions:

print $esi + $ebx + 4

You can dereference the memory using the * operator (like in C):

print *$ecx

will print the contents of the memory location pointed to by ecx.

While you can't directly type in assembly code, you can translate the expression into something more high-level, like this:

print $eax - ($esi * $ebx)

Also, you can convert to various types using casts to C data-types, e.g.

print (char)$ecx

would print the contents of ecx as a character.

print *(char**)$ecx

which would interpret ecx as a pointer to char*, which you then dereference. So you'd see the contents of the string at the address contained in ecx.

This is just the tip of the iceberg though. gdb is very powerful tool. You might also find the display command useful. It's basically the same as print, except it will repeat the print command whenever the code is stopped (useful with breakpoints). You can examine most registers using info registers, or info all-registers if you're masochistic.

You can also change the contents of registers, using set:

set $eax = 20

and stepi through instructions, or continue running the program.

P.S. You'll probably want to learn how to set breakpoints, etc., if you don't know that.

Related Topic