Reputation: 9512
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.
Upvotes: 7
Views: 8591
Reputation: 4969
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.
Upvotes: 7