Linux下汇编调试器GDB的使用

GDB 是GNU开源组织发布的一个强大的Linux/Unix下的程序调试工具。大家是否早已习惯了Windows下图形界面方式像VC、BCB等IDE的调试器,但如果你是在Linux平台下做软件调试,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。

先来看个实例: 

reader@cg:~/source $ gdb -q  (gdb) set dis intel  (gdb) quit  reader@cg:~/source $ echo "set dis intel" > ~/.gdbinit  reader@cg:~/source $ cat ~/.gdbinit  set dis intel  reader@cg:~/source $  

现在将GDB配置成为了使用Intel语法,让我们首先来认识Intel语法。在Intel语语法中,汇编指令一般遵循下面这种形式:
operation <destination>, <source>
目的操作数和源操作数可以是寄存器、内存地址或数值。操作通常是直观的助记符:mov操作会将源操作数中的值移动到目的操作数中,sub操作会减去,inc指令会增加等。例如,下面的指令将会扣ESP中的值移动到EBP中,然后从ESP中减去8(结果存储在ESP中)。
8048375:        89 e5                 mov    ebp,esp
8048377:        83 ec 08              sub    esp,0x8
还有用于控制执行流程的操作。cmp操作用于对数值进行比较,并且基本上所有以j为首字母的操作都用于转移到代码的不同部分(转移到哪一部分取决于比较的结果)。下面的例子中,首先将位于EBP中的一个4字节的值减去4与数值9进行比较。下一条指令是如果小于等于则转移的简写,它参考的是前一个比较的结果。如果那个数小于或等于9,那么程序就会转移到Ox8048393处的指令执行。否则,就转向下一条无条件转移指令执行。如果那个数不小于或等于9,那么程序执行就会转移到Ox80483a6处。
804838b:        83 7d fc 09           cmp    DWORD PTR [ebp-4],0x9
804838f:        7e 02                 jle    8048393 <main+0x1f>
8048391:        eb 13                 jmp    80483a6 <main+0x32>
这些例子来自于我们先前的反汇编,并且我们已经将调试工具配置为使用Intel语法,所以让我们使用调试工具在汇编指令级别上单步调试第一个程序吧。
GCC编译程序可以使用-g标记来包含附加的调试信息,这些调试信息会使得GDB能够访问源代码。
 

reader@cg:~/source $ gcc -g firstprog.c   reader@cg:~/source $ ls -l a.out  -rwxr-xr-x 1 matrix users 11977 Jul 4 17:29 a.out  reader@cg:~/source $ gdb -q ./a.out  Using host libthread_db library "/lib/libthread_db.so.1".  (gdb) list  1       #include <stdio.h> 2  3       int main()  4       {  5               int i;  6               for(i=0; i < 10; i++)  7               {   8                       printf("Hello, world!\n");  9               }  10      }  (gdb) disassemble main  Dump of assembler code for function main():  0x08048384 <main+0>:    push   ebp  0x08048385 <main+1>:    mov    ebp,esp  0x08048387 <main+3>:    sub    esp,0x8  0x0804838a <main+6>:    and    esp,0xfffffff0  0x0804838d <main+9>:    mov    eax,0x0  0x08048392 <main+14>:   sub    esp,eax   0x08048394 <main+16>:   mov    DWORD PTR [ebp-4],0x0   0x0804839b <main+23>:   cmp    DWORD PTR [ebp-4],0x9  0x0804839f <main+27>:   jle    0x80483a3 <main+31> 0x080483a1 <main+29>:   jmp    0x80483b6 <main+50> 0x080483a3 <main+31>:   mov    DWORD PTR [esp],0x80484d4  0x080483aa <main+38>:   call   0x80482a8 <_init+56> 0x080483af <main+43>:   lea    eax,[ebp-4]  0x080483b2 <main+46>:   inc    DWORD PTR [eax]  0x080483b4 <main+48>:   jmp    0x804839b <main+23> 0x080483b6 <main+50>:   leave  0x080483b7 <main+51>:   ret  End of assembler dump.  (gdb) break main  Breakpoint 1 at 0x8048394: file firstprog.c, line 6.  (gdb) run  Starting program: /cg/a.out   Breakpoint 1, main() at firstprog.c:6  6               for(i=0; i < 10; i++)  (gdb) info register eip  eip            0x8048394        0x8048394  (gdb)   

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wyfgjj.html