在分析/研究一些C/C++代码问题的时候,我们经常都希望了解得越深入越好,甚至希望深入到汇编级别。有时候问题很简单,例如下面比较两种整数变量自减写法的效率,这样简单的问题一定要通过写一个完整的测试程序,并千万次的重复调用来进行测时吗? 真不一定,通过反汇编的方式就可以知道了,下面介绍一些对C/C++代码反汇编的方法:
方法一:objdump方法,适合简单问题的分析/研究
1,写一个简单的函数,包含想分析/研究的问题,例如比较两种整数变量自减写法的效率
$ vi tmp.c
void tmp()
{
int i = 0;
int j = 0;
i = i - 1;
--j;
}
2,编译该文件
$ gcc -c tmp.c
3,查看其对应的汇编,这样看就知道在这个例子中这两种写法没什么差别
$ objdump -d tmp.otmp.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <tmp>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp)
b: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%rbp)
12: 83 6d fc 01 subl $0x1,-0x4(%rbp)
16: 83 6d f8 01 subl $0x1,-0x8(%rbp)
1a: 5d pop %rbp
1b: c3 retq
方法二:直接编译方式
对方法一中的tmp.c文件只用用gcc -S tmp.c编译便可得到tmp.s文件,查看即可
.text
.globl tmp
.type tmp, @function
tmp:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $0, -4(%rbp)
movl $0, -8(%rbp)
subl $1, -4(%rbp)
subl $1, -8(%rbp)
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size tmp, .-tmp
.ident "GCC: (GNU) 4.6.3 20120306 (Red Hat 4.6.3-2)"
.section .note.GNU-stack,"",@progbits
方法三:gdb调试方法
1,写一个简单程序,包含想分析/研究的问题
$ vi tmp.c
int main()
{
int i = 0;
int j = 0;
i = i - 1;
--j;
}
2,编译成可执行文件
$gcc -g tmp.c
3,gdb中“disass 函数名”即可
$ gdb a.out
(gdb) disass main
Dump of assembler code for function main:
0x0000000000400474 <+0>: push %rbp
0x0000000000400475 <+1>: mov %rsp,%rbp
0x0000000000400478 <+4>: movl $0x0,-0x4(%rbp)
0x000000000040047f <+11>: movl $0x0,-0x8(%rbp)
0x0000000000400486 <+18>: subl $0x1,-0x4(%rbp)
0x000000000040048a <+22>: subl $0x1,-0x8(%rbp)
0x000000000040048e <+26>: pop %rbp
0x000000000040048f <+27>: retq
End of assembler dump.