《linux内核分析》第一次课 实验作业
解释main.c的汇编码的堆栈变化
实验截图如下图所示:
下面从main函数开始进行分析(三个可变数值从上到下分别为4,7,4):
不妨假设一开始为空栈,初始位置为0,ebp=esp,以下用行号进行标记
18:esp指向位置(1),位置(1)的值为esp的地址
19:使ebp指向与esp相同的地址(位置1)
20:esp指向位置(2)
21:位置(2)的值为7
22:调用f函数(标号):esp指向位置(3),位置(3)的值为eip的地址,将f的地址放到eip中
09:esp指向位置(4),位置(4)的值为ebp的地址
10:使ebp指向与esp相同的地址(位置4)
11:esp指向位置(5)
12:将ebp上移两个位置(位置2)的地址作为eax的地址,eax=7
13:使esp所在位置(位置5)的值为eax的地址
14:调用g函数:esp指向位置(6),位置(6)的值为eip的地址,将g的地址放到eip中
02:esp指向位置(7),位置(7)的值为ebp的地址
03:使ebp指向与esp相同的地址(位置7)
04:将ebp上移两个位置(位置5)的地址作为eax的地址,eax=7
05:eax的值加上4,eax=11
06:ebp指向位置(4),esp指向位置(6)
07:eip重新指向行号15
15:esp指向ebp的地址(位置4),ebp指向位置(1),esp指向位置(3)
16:eip重新指向行号23
23:eax的值加上4,eax=15
24:esp指向ebp的地址(位置1),ebp指向位置(0),esp指向位置(0)
25:eip重新指向main函数调用前中断的地址,运行其他指令
--------------------------------------------------------------------
计算机是如何工作的:
1. 采用冯诺依曼体系结构,CPU通过总线与内存连接,CPU中有IP负责执行语句并移动至下一个指令,内存中存放着具体指令和数据。
2. 寄存器分为通用寄存器和段寄存器,通用寄存器负责记录累加值、基地址、堆栈基地址与顶地址、变址、计数值等,段寄存器负责记录代码段、数据段、附加段和堆栈段。
3. IP指向代码段寄存器,随着逐条执行IP,代码段寄存器(CS)中的指令被一一执行,而CS也可以影响IP的指向,从而更改执行的流程,组成复杂的控制结构。
-------------------------------------------------------------------
c语言文件是如何被编译为汇编语言的:
1. 进入函数
2. 调用子函数,用eax收集函数返回值
3. 执行子函数,将返回值赋值到eax
4. 退出函数
------------------------------------------------------------------
汇编语言与堆栈的关系:
1. enter:在堆栈中记录当前ebp的地址,并将esp的地址下移一位作为函数的私有栈
2. call:将eip按顺序应该执行的地址压栈,并将子函数的地址赋值给eip,从而执行子函数
3. leave:enter的逆动作,将esp的地址赋值为ebp的上一位,并将ebp指向母函数的栈底,表示退出该栈(栈中信息将在下次使用时覆盖)
4. ret:将eip重新定向到当前的栈的地址
其中call和ret成对使用(call在母函数,ret在子函数),enter和leave成对使用(都在同一函数中)
————————————————————————————————————————
潘聪 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。