码迷,mamicode.com
首页 > 其他好文 > 详细

反汇编一个简单的C程序

时间:2015-03-08 21:26:08      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:

long#long + 原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

C程序代码:

技术分享
 1 int g(int x)
 2 {
 3   return x + 3;
 4 }
 5 
 6 int f(int x)
 7 {
 8   return g(x);
 9 }
10 
11 int main(void)
12 {
13   return f(8) + 1;
14 }
View Code

编译命令:

gcc -S -o main.s main.c -m32

编译得到的汇编代码:

技术分享
    .file    "main.c"
    .text
    .globl    g
    .type    g, @function
g:
.LFB0:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    movl    8(%ebp), %eax
    addl    $3, %eax
    popl    %ebp
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE0:
    .size    g, .-g
    .globl    f
    .type    f, @function
f:
.LFB1:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $4, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    g
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE1:
    .size    f, .-f
    .globl    main
    .type    main, @function
main:
.LFB2:
    .cfi_startproc
    pushl    %ebp
    .cfi_def_cfa_offset 8
    .cfi_offset 5, -8
    movl    %esp, %ebp
    .cfi_def_cfa_register 5
    subl    $4, %esp
    movl    $8, (%esp)
    call    f
    addl    $1, %eax
    leave
    .cfi_restore 5
    .cfi_def_cfa 4, 4
    ret
    .cfi_endproc
.LFE2:
    .size    main, .-main
    .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits
View Code

过滤掉其中的伪代码指令:

cat main.s | grep -v "\."

得到干净的汇编代码:

技术分享
g:
    pushl    %ebp
    movl    %esp, %ebp
    movl    8(%ebp), %eax
    addl    $3, %eax
    popl    %ebp
    ret
f:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    8(%ebp), %eax
    movl    %eax, (%esp)
    call    g
    leave
    ret
main:
    pushl    %ebp
    movl    %esp, %ebp
    subl    $4, %esp
    movl    $8, (%esp)
    call    f
    addl    $1, %eax
    leave
    ret
View Code

下面对得到的干净的汇编代码进行分析:

main:
    pushl   %ebp                # (%esp) - 4 -> %esp; (%ebp) -> (%esp)
    movl    %esp, %ebp          # (%esp) -> %ebp
    subl    $4, %esp            # (%esp) - 4 -> %esp
    movl    $8, (%esp)          # 8 -> (%esp)
    call    f                   # (%esp) - 4 -> %esp; (%eip) -> (%esp); f -> %eip

f:
    pushl %ebp # (%esp) - 4 -> %esp; (%ebp) -> (%esp)
    movl %esp, %ebp # (%esp) -> %ebp
    subl $4, %esp # (%esp) - 4 -> %esp
    movl 8(%ebp), %eax # (%ebp + 8) -> %eax
    movl %eax, (%esp) # (%eax) -> (%esp)
    call g # (%esp) - 4 -> %esp; (%eip) -> (%esp); g -> %eip

g:
  pushl %ebp # (%esp) - 4 -> %esp; (%ebp) -> (%esp)
    movl %esp, %ebp # (%esp) -> %ebp
    movl 8(%ebp), %eax # (%ebp + 8) -> %eax
    addl $3, %eax # (%eax) + 3 -> %eax
    popl %ebp # (%esp) -> %ebp; (%esp) + 4 -> %esp
    ret # (%esp) -> %eip; (%esp) + 4 -> %esp

    leave # (%ebp) -> %esp; (%esp) + 4 -> %esp
    ret # (%ebp) -> %esp; (%esp) -> %ebp; (%esp) + 4 -> %esp
addl $1, %eax # (%eax) + 1 -> %eax leave # (%ebp) -> %esp; (%esp) -> %ebp; (%esp) + 4 -> %esp; ret # (%esp) -> %eip; (%esp) + 4 -> %esp

关于上述分析的几点说明:
上述汇编代码按照程序执行流进行排列的, 每行汇编代码右侧的注释说明了该行汇编代码所完成的操作及执行后的效果。上述注释代码中出现在‘->‘左侧的是一个值,出现在‘->‘右侧的是一个地址, 表示将左侧的值写入到右侧的地址中。

总结
  通过对一个简单的C程序的汇编代码进行分析, 对计算机工作过程有了更深的理解: CS:EIP确定了CPU执行流!

反汇编一个简单的C程序

标签:

原文地址:http://www.cnblogs.com/long3216/p/4322221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!