1_简单的C程序反汇编及分析

版权声明:陈诚
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
=================================================================
这是linux系统分析课程的第一个实验,比较简单的一个实验,要能看懂AT&T汇编指令并且能够理解程序运行时内存栈上动态变化的过程。

1.进入实验楼的环境,按照实验要求进行。先用vi编辑器打开一个空白文件命名为main.c,然后复制粘贴给出的c代码。

2.敲入命令:gcc -S -o main.s main.c -m32,将c代码反汇编成汇编代码,然后去除所有以圆点(.)开头的行,结果如下图所示。


 3.接下来结合图示详细分析这段汇编代码在栈上是如何动态运行的
--------------------------------------------
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
-----------------------------------------
程序从main函数开始执行
pushl      % ebp
movl       %esp, % ebp
这两句在汇编中只要是函数开始一般都会有,与宏指令Enter功能相同,栈中情况如下图:

subl $4, %esp // 将esp寄存器中的值减4,即在栈上分配一个存储空间
movl $8, (%esp) // 将立即数8放入esp寄存器指向的内存单元中,即在调用函数前将函数需要的参数压栈
这两句执行后,栈中情况如下图:
1_简单的C程序反汇编及分析_第1张图片

call f // 调用f函数,执行这句前先将下条语句的地址压栈(addl  $1, % eax 这条语句的地址)
1_简单的C程序反汇编及分析_第2张图片
--------------------------------------
下面进入f函数:
f:
pushl       % ebp
movl        %esp, % ebp
这两句和main函数开始的功能一样,栈中情况如下图:

subl       $4, %esp
movl      8(% ebp), % eax // 将ebp值加8后放入eax寄存器中
movl     % eax, (%esp)
这三句执行后,栈中情况如下图:

call g // 下面调用g函数


---------------------------
下面进入g函数:

g:
pushl       % ebp
movl        %esp, % ebp
上面两句不解释了,执行后栈中情况如下图



movl      8(% ebp), % eax
addl       $3, % eax
这两句执行完成后,栈中情况如下图:
1_简单的C程序反汇编及分析_第3张图片
popl     % ebp
ret
这两句执行完成后,栈中情况如下图:
1_简单的C程序反汇编及分析_第4张图片


---------------------------
下面返回f函数继续执行:

leave  // 相当于 movl   % ebp, %esp 和 popl   % ebp这两句的功能
ret  // 将栈中的值弹出到eip
执行后栈中情况如下图:
1_简单的C程序反汇编及分析_第5张图片

--------------------------------------
返回main函数继续执行

addl $1, % eax // eax寄存器值加一,此时eax寄存器中保存的是返回的结果,此时eax=12

leave // 相当于 movl % ebp, %esp 和popl % ebp这两句的功能

ret // 将栈中的值弹出到eip


----------------------------------
总结:
关于计算机是如何工作的。这个问题比较大,不同的角度回答,答案都不一样。
从cpu的角度看,就是输入、运算、输出(可能也没有输出)。从程序角度看,当程序运行时,需要在内存中的栈上分配一段空间,伴随着程序的运行,esp,ebp,eip等各个寄存器发生变化。
cpu将代码段中的语句,经过取指、翻译、执行后的结果,可以输出I/O、写回数据段等。接着再由eip自加一生成下一条指令的地址,继续执行。关于程序运行时栈中的变化情况,博客正文中已结合图示演示。

你可能感兴趣的:(linux,kernel)