用gdb 查看汇编代码, 采用disassemble 和 x 命令。 nexti, stepi 可以单步指令执行

如下例:

------------------------------------------------------------
源代码:
------------------------------------------------------------
[root@hjj ~]# cat 1.c
#include <stdio.h>

int main(int argc, char *argv[])
{
    int size=sizeof("hjj");
    printf("size is %d\n",size);
    return 0;
}

------------------------------------------------------------
编译
------------------------------------------------------------
ot@hjj ~]# gcc -g3 -o 1 1.c

------------------------------------------------------------
调试
------------------------------------------------------------
[root@hjj ~]# gdb 1
GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/1...done.
(gdb) b main
Breakpoint 1 at 0x4004d3: file 1.c, line 5.
(gdb) r
Starting program: /root/1

Breakpoint 1, main (argc=1, argv=0x7fffffffe5c8) at 1.c:5
5        int size=sizeof("hjj");

------------------------------------------------------------

观察. 用disasseble.

/m 源码和汇编一起排列

/r 还可以看到16进制代码

------------------------------------------------------------
(gdb) disassemble /m main
Dump of assembler code for function main:
4    {
   0x00000000004004c4 <+0>:    push   %rbp
   0x00000000004004c5 <+1>:    mov    %rsp,%rbp
   0x00000000004004c8 <+4>:    sub    $0x20,%rsp
   0x00000000004004cc <+8>:    mov    %edi,-0x14(%rbp)
   0x00000000004004cf <+11>:    mov    %rsi,-0x20(%rbp)

5        int size=sizeof("hjj");
=> 0x00000000004004d3 <+15>:    movl   $0x4,-0x4(%rbp)

6        printf("size is %d\n",size);
   0x00000000004004da <+22>:    mov    $0x4005f8,%eax
   0x00000000004004df <+27>:    mov    -0x4(%rbp),%edx
   0x00000000004004e2 <+30>:    mov    %edx,%esi
   0x00000000004004e4 <+32>:    mov    %rax,%rdi
   0x00000000004004e7 <+35>:    mov    $0x0,%eax
   0x00000000004004ec <+40>:    callq  0x4003b8 <printf@plt>

7        return 0;
   0x00000000004004f1 <+45>:    mov    $0x0,%eax

8    }
   0x00000000004004f6 <+50>:    leaveq
   0x00000000004004f7 <+51>:    retq   

End of assembler dump.
------------------------------------------------------------
用 x/i 可以查看指令
------------------------------------------------------------
(gdb) x/15i main
   0x4004c4 <main>:    push   %rbp
   0x4004c5 <main+1>:    mov    %rsp,%rbp
   0x4004c8 <main+4>:    sub    $0x20,%rsp
   0x4004cc <main+8>:    mov    %edi,-0x14(%rbp)
   0x4004cf <main+11>:    mov    %rsi,-0x20(%rbp)
=> 0x4004d3 <main+15>:    movl   $0x4,-0x4(%rbp)
   0x4004da <main+22>:    mov    $0x4005f8,%eax
   0x4004df <main+27>:    mov    -0x4(%rbp),%edx
   0x4004e2 <main+30>:    mov    %edx,%esi
   0x4004e4 <main+32>:    mov    %rax,%rdi
   0x4004e7 <main+35>:    mov    $0x0,%eax
   0x4004ec <main+40>:    callq  0x4003b8 <printf@plt>
   0x4004f1 <main+45>:    mov    $0x0,%eax
   0x4004f6 <main+50>:    leaveq
   0x4004f7 <main+51>:    retq   
------------------------------------------------------------
$pc 指向当前程序运行地址
------------------------------------------------------------
(gdb) x/5i $pc
=> 0x4004d3 <main+15>:    movl   $0x4,-0x4(%rbp)
   0x4004da <main+22>:    mov    $0x4005f8,%eax
   0x4004df <main+27>:    mov    -0x4(%rbp),%edx
   0x4004e2 <main+30>:    mov    %edx,%esi
   0x4004e4 <main+32>:    mov    %rax,%rdi
(gdb)
--------------------------------------------------------------------------------
用gdb 调试汇编代码(二进制代码).
查看:
disassembler $pc
display/i $pc
x/i $pc

执行: 单指令。
ni;
si:

 

p $eax

p $edi 等可以查看寄存器.

在gdb中 敲入help layout

(gdb) help layout
Change the layout of windows.
Usage: layout prev | next | <layout_name>
Layout names are:
   src   : Displays source and command windows.
   asm   : Displays disassembly and command windows.
   split : Displays source, disassembly and command windows.
   regs  : Displays register window. If existing layout
           is source/command or assembly/command, the
           register window is displayed. If the
           source/assembly/command (split) is displayed,
           the register window is displayed with
           the window that has current logical focus.

然后你可以用layout 去调试,很方便, 例如 layout asm.

还是用vim 最为gdb调试前端比较好,如果是源码级调试就很爽了.可以直接查看寄存器内容,

例如: print $eax

 print $es

=======================================

在GDB环境下可以通过如下设置让汇编语言按照inter格式或者是AT&T的格式显示 
set disassembly-flavor intel 转换为intel格式的汇编 
set disassembly-flavor att 转换为AT&T格式的汇编 
也可以把这个配置到文件里面: 

sudo echo “set disassembly-flavor intel”> ~/.gdbinit

可以使用 info line 命令来映射一个源码行到程序地址,然后使用命令disassemble/disass显示一个地址范围的机器指令

 info line main.main
Line 49 of "/datainfo/work/golang/gotest/src/main.go" starts at address 0x4726e0 <main.main> and ends at 0x4726ef <main.main+15>.


通过disassemble add1 add2 来显示add1到2之间的汇编代码

disass 0x4726e0,0x4726ef
Dump of assembler code from 0x4726e0 to 0x4726ef:
   0x00000000004726e0 <main.main+0>:    mov    %fs:0xfffffffffffffff8,%rcx
   0x00000000004726e9 <main.main+9>:    cmp    0x10(%rcx),%rsp
   0x00000000004726ed <main.main+13>:   jbe    0x47276c <main.main+140>
End of assembler dump.

也可以显示指定地址后面的汇编代码:

disass 0x4726e0
Dump of assembler code for function main.main:
   0x00000000004726e0 <+0>: mov    %fs:0xfffffffffffffff8,%rcx
   0x00000000004726e9 <+9>: cmp    0x10(%rcx),%rsp
   0x00000000004726ed <+13>:    jbe    0x47276c <main.main+140>
   0x00000000004726ef <+15>:    sub    $0x38,%rsp
   0x00000000004726f3 <+19>:    mov    %rbp,0x30(%rsp)
   0x00000000004726f8 <+24>:    lea    0x30(%rsp),%rbp
   0x00000000004726fd <+29>:    movq   $0x1,0x10(%rsp)
   0x0000000000472706 <+38>:    lea    0x10(%rsp),%rax
   0x000000000047270b <+43>:    mov    %rax,0x18(%rsp)
   0x0000000000472710 <+48>:    lea    0x3ea09(%rip),%rcx        # 0x4b1120 <go.itab.*types.Integer,types.LessAdder>
   0x0000000000472717 <+55>:    mov    %rcx,0x20(%rsp)
   0x000000000047271c <+60>:    mov    %rax,0x28(%rsp)
   0x0000000000472721 <+65>:    callq  0x427330 <runtime.printlock>
   0x0000000000472726 <+70>:    mov    0x20(%rsp),%rax
   0x000000000047272b <+75>:    mov    0x28(%rsp),%rcx
   0x0000000000472730 <+80>:    mov    %rax,(%rsp)
   0x0000000000472734 <+84>:    mov    %rcx,0x8(%rsp)
   0x0000000000472739 <+89>:    callq  0x427e60 <runtime.printiface>
   0x000000000047273e <+94>:    callq  0x4275b0 <runtime.printnl>
   0x0000000000472743 <+99>:    callq  0x4273b0 <runtime.printunlock>
   0x0000000000472748 <+104>:   movq   $0x6,(%rsp)
   0x0000000000472750 <+112>:   callq  0x472680 <main.t1>
   0x0000000000472755 <+117>:   movq   $0x7,(%rsp)
   0x000000000047275d <+125>:   callq  0x4726c0 <main.t2>
   0x0000000000472762 <+130>:   mov    0x30(%rsp),%rbp
   0x0000000000472767 <+135>:   add    $0x38,%rsp
   0x000000000047276b <+139>:   retq   
   0x000000000047276c <+140>:   callq  0x44e480 <runtime.morestack_noctxt>
   0x0000000000472771 <+145>:   jmpq   0x4726e0 <main.main>
End of assembler dump.



disassemble : 
1,不带参数:默认的反汇编范围是所选择地址附近的汇编代码; 
2,单个参数:当然也可以是函数名,因为函数名也是一个 地址; 
3,两个参数:就是内存地址范围;
 

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐