202020211 20209327 《Linux内核原理与分析》第二周作业

反汇编C程序

目录

  • 反汇编源程序
  • 分析汇编过程
  • 问题与总结
  • 参考链接

一、反汇编源程序

对于这样一个源程序:

// main.c
int g(int x)
{
    return x + 2;
}

int f(int x)
{
    return g(x);
}

int main(void)
{
    return f(4) + 3;
}

通过命令gcc –S main.c –o main.s -m32将main.c编译成汇编代码,得到如图的汇编代码文件main.s:

通过g/\.s*/d去掉多余辅助信息:

得到可供分析的汇编代码:

二、分析汇编过程

对如下的汇编代码进行分析:

1  g:
2 	 pushl	 %ebp
3 	 movl	 %esp, %ebp
4 	 movl	 8(%ebp), %eax
5 	 addl	 $2, %eax
6 	 popl	 %ebp
7 	 ret
8  f:
9 	 pushl	 %ebp
10 	 movl	 %esp, %ebp
11 	 pushl	 8(%ebp)
12 	 call	 g
13	 addl	 $4, %esp
14	 leave
15	 ret
16 main:
17 	 pushl	 %ebp
18	 movl	 %esp, %ebp
19	 pushl	 $4
20	 call	 f
21	 addl	 $4, %esp
22	 addl	 $3, %eax
23	 leave
24	 ret

初始时栈的状态如下:

从main函数开始执行,首先执行17 pushl %ebp,esp沿着地址递减的方向指向下一个存储单元,将ebp现在指向的存储单元的地址压入栈中,即将2000入栈

执行18 movl %esp, %ebp,将ebp移动至esp所指的存储单元

执行19 pushl $4,将参数4压入栈中

执行20 call f,调用f函数,相当于将下一条指令的地址,即EIP中的值21压入栈中,并将f函数的第一条指令的地址9存入EIP当中,表示下一条执行的指令在第9行

执行9 pushl %ebp,将ebp指向的存储单元的地址1996入栈

执行10 movl %esp, %ebp,将ebp移动至esp所指的存储单元

执行11 pushl 8(%ebp),相当于ebp沿地址递增的方向移动两个存储单元,将其中存储的数据压入栈中,即将4入栈

执行12 call g,调用g函数,将当前EIP中的值13入栈,将g函数的第一条指令地址2存入EIP寄存器中,下一条执行的指令在第2行

执行2 pushl %ebp,将ebp指向的存储单元的地址1984入栈

执行3 movl %esp, %ebp,将ebp移动至esp所指的存储单元

执行4 movl 8(%ebp), %eax,相当于ebp沿地址递增的方向移动两个存储单元,将其中存储的数据4存入EAX寄存器中

执行5 addl $2, %eax,将EAX寄存器中的值加2,结果为6

执行6 popl %ebp,将当前栈顶的值1984弹出栈,并将esp移动至地址为1984的存储单元,esp沿地址递增的方向移动一个存储单元

执行7 ret,将当前栈顶的值13弹出栈,并存入EIP当中,下一条执行的指令地址为13

执行13 addl $4, %esp,将esp沿着地址递增的方向移动一个存储单元

执行14 leave,将栈顶的值1996弹出至ebp,即将ebp移动至地址为1996的存储单元,esp沿地址递增的方向移动一个存储单元

执行15 ret,将当前栈顶的值21弹出至EIP寄存器中,即下一条执行的指令在第21行

执行21 addl $4, %esp,将esp沿着地址递增的方向移动一个存储单元

执行22 addl $3, %eax,将EAX寄存器中的值加3,结果为9

执行23 leave,将当前栈顶的值2000弹出栈,将ebp移动至地址为2000的存储单元,同时将esp沿地址递增的方向移动一个存储单元。此时堆栈空间回到了main函数执行前的状态,恢复至空栈。

执行24 ret,执行完毕。

三、问题与总结

阅读《庖丁解牛Linux内核分析》第一章之后,对计算机的工作方式有了更深的了解,对于汇编代码的执行过程和堆栈空间有了进一步的理解和认识。在第一次尝试对汇编代码进行分析时,由于对汇编语言的了解不够深入,导致最开始的分析过程进入了误区。

问题:在执行指令movl 8(%ebp), %eax时,ebp指针是否进行了移动?

这条指令的意思是:将地址[ebp+8]指向的数据存入eax寄存器中。所以我个人的理解是在ebp的基础上进行地址计算,将加8之后的地址所指向的数据存入eax中,ebp应该是不动的。

最后对计算机的工作方式进行一个总结:由于计算机的指令与数据都保存在内存中,因此当计算机开始工作时,通过控制器在内存中取出指令,根据指令的内容要求,从内存中取出数据并进行指定的运算或逻辑操作,再将结果送入内存中的指定地址中。随着程序的编排,计算机将指令逐条取出,自动完成一条条指令所规定的操作,直至遇到停止指令。

四、参考链接

原文地址:https://www.cnblogs.com/TracerElena/p/13835259.html