反汇编 C 语言程序

来源:互联网 发布:qq旋风连接不到网络 编辑:程序博客网 时间:2024/04/27 16:49

实验环璄:网易云课堂 实验楼64位Linux虚拟机

张磊 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

main.c 文件:

#include <stdio.h>int g(int x){  return x + 3;} int f(int x){  return g(x);} int main(void){  return f(8) + 1;}
使用命令:
gcc –S –o main.s main.c -m32


生成如下的汇编代码,去掉多余部分后


常用指令解释:

CALL指令:

用来调用一个函数或过程,此时,下一条指令地址会被压入堆栈,以备返回时能恢复执行下条指令。


 RET指令:

用来从一个函数或过程返回,之前CALL保存的下条指令地址会从栈内弹出到EIP寄存器中,程序转到CALL之前下条指令处执行

ENTER指令:

建立当前函数的栈框架,即相当于以下两条指令:

        pushl   %ebp        movl    %esp,%bp
LEAVE指令:

释放当前函数或者过程的栈框架,即相当于以下两条指令:

        movl %ebp, %esp        popl %ebp
反汇编代码实验过程:

1.首先从main函数开始

L18       pushl %ebp
把 ebp 的地址存储到 标号为0的内存地址


L19   movel %esb, %ebp
把 ebp的值赋给 esp,ebp,esp 向低地址移动4个字节,如图中,移动一个标号。

L20    subl    $4, %espL21    movl   $8, (%esp)    

subl $4, %esp 把 esp 减4,也就是向低地址移动4个字节,即图中的标号加1。movl $8, (%esp) 即把8把到 esp 所指地址内。


L22    call    fL23    addl   $1, %eax

call f 执行的时候 eip 指针会指向函数 f 的地址,同时 esp向低址移动4个字节,即下移一个标号到3


2.f 函数中的栈调用过程

L9    pushl    %ebpL10   movl     %esp, %ebp

首先 push ebp时,esp 已经指向 标号4的位置,把 esp 的值重向赋给 ebp,ebp 也指向标号4的位置。

L11    subl    $4, %espL12    movl   8(%ebp), %eaxL13    movl   %eax, (%esp)

L11  subl %4, %esp 把 esp 指向下一个标号即5,L12 movl 8(%ebp), %eax 把 ebp变址寻址8后 ,即标号2的位置,把 ebp所指的标号2 的值8赋给 eax, L13  movl %eax, (%esp) 把 eax 的值 8 放入 esp 所指的地址内。


L14    call    g

L14 call g 把 eip 向下移动一个标号,即esp把向标号6,标号6内存入 eip(14),eip指向 g 函数。



 3.g 函数栈的调用过程

<span style="font-size:18px;">L2    pushl    %ebpL3    movl     %esp, %ebp</span>

L2 pushl %ebp 把 esp指向下一个标号7的位置,把 ebp 4放入标号7中,L3 movl %esp, %ebp 把 esp 的值赋给 ebp,即 ebp也指向标号7的位置。


L4    movl     8(%ebp), %eaxL5    addl     $3, %eaxL6    popl     %ebp

L4 movl 8(%ebp), %eax 变址寻址8后,标号减2,取标号5中的值8赋给 eax,即 eax=8,L5 addl $3, %eax 给 eax 再加3,即 eax=11,L6 popl %ebp把标号7中的 ebp 4赋给 ebp,即 ebp 指向标号4,esp 把向标号6。


L7    ret

L7 ret 就是 popl %eip(*),即 esp把向了标号5,同时 eip 把向了第15行代码即L15 leave。


3.g 函数调用结束,eip 指向了 f 函数

L15    leave

L15 leave 相当于movl %ebp, %esp,把 esp 把向了标号4,再 popl %ebp,把 ebp 指向标号1的位置,再把 esp 指向3的位置。

L16    ret

ret 就是 popl %eip(*),即 esp把向了标号2,同时 eip 把向了第23行代码即L23 addl $1, %eax,eax=11,再加1后,eax 的值为12。


4.f 函数调用结束,eip 指向 main 函数

L24    leaveL25    ret

L24 leave 相当于movl %ebp, %esp,把 esp 把向了标号1,再 popl %ebp,把 ebp 指向标号0的位置,再把 esp 指向0的位置。这个时候栈又回到了 main 函数之前的堆栈了。


到这里整个程序就调用结束了。

小结:

程序的堆栈调用大体过程是堆栈先向下增加,然后再向上还原的一个过程,整个程序通过指令线性流过 CPU。

计算机工作原理:

1、单任务计算机是如何工作的
    单任务计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存贮器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去。接下来,再取出第二条指令,在控制器的指挥下完成规定操作。依此进行下去,直至遇到停止指令。
  程序与数据一样存贮,按程序编排的顺序,一步一步地取出指令,自动地完成指令规定的操作是单任务计算机最基本的工作原理。
2、多任务计算机是如何工作的
    多任务,就是同一时间给多个程序运行处理数据。Unix是实时的、分布式系统,采用时间片方式,轮流给多个提交CPU处理请求的进程分配资源,支持多用户、多任务处理。Windows多任务处理采用的是虚拟机技术,在内存中创建逻辑微机(也是通过时间片轮流占用CPU),由它来运行处理程序。所谓多任务处理,就是指同时运行多个程序并且程序之间可以随意切换。

0 0
原创粉丝点击