通过一段反汇编代码浅析计算机工作方式

本文详细介绍了如何通过实验反汇编一个简单的C程序,理解其对应的汇编代码,进而分析计算机内部工作原理。具体包括实验环境设置、C程序代码、汇编代码解析、以及单核计算机在单任务和多任务下的工作方式。通过实例阐述,让读者能够直观地理解计算机底层运行机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

通过实验“通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的”,通过反汇编,得到一段C程序的对应的汇编代码,笔者将结合汇编代码细致分析各个寄存器和堆栈的变化,以此来说明计算机的工作方式。

1.反汇编,分析汇编代码

1.1 实验环境: 

本实验环境是由实验楼提供。读者可以通过 http://www.shiyanlou.com/courses/195访问。

1.2 简单的一段C程序:

int g(int x)
{
      return x + 6;
}

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

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

通过 gcc –S –o main.s main.c -m32 得到汇编代码(已经删除汇编代码元数据的汇编代码)如下图:

1.3  汇编代码分析

分析上述汇编代码,从main标签开始。

假设内存栈地址从0标记处开始,(0,1,2,3....等各标记表示4字节内存单元,当然,栈地址是向下增长的,在此处为了方便讲述)。18,19行开始初始化ebp,esp 寄存器,如下图,ebp,esp都指向内存单元1处。这是因为 pushl %ebp 即为subl $4,%esp 、movl %ebp %esp 。

调用函数f之前,call f ;函数需要将参数压栈,在这里参数2入栈,那么call f 在这里做了什么呢?第一,将eip寄存器入栈,此时的eip指向call f 的下一个指令,即 addl $3,%eax;第二,将f开始执行的指令地址放入到eip中,接下来的g函数调用也是如此道理。来个示意图吧:

接下来到f标签处:

首先,前两个指令,压栈ebp,并且将ebp和esp指向同一位置,即指向4标记处。subl $4,%esp,接下来11,12,13 这三条指令,也是为了将参数压栈,该参数依旧是2。再来一张图:


接下来又进行一次函数调用,来到了g标签处:压栈eip,压栈ebp,取出参数2,addl指令,进行加运算,将2+6的值放入eax寄存器中,再附图一张~:


接下来将数值存在eax寄存器中之后,就开始不断的弹栈了。在弹栈的过程中,需要注意的一点是leave 指令, leave指令 是movl %ebp %esp ;popl %ebp,leave指令来释放被调用函数的堆栈空间,并恢复自己的基栈地址。ret指令就是popl %eip 。

最终结果保存在eax寄存器中。

2.简述单核计算机工作方式

2.1 单任务下:

在单任务下,计算机先把机器码(.o文件,exe文件etc)加载到内存,初始化寄存器(ebp,esp,eip,PC);PC存放当前执行指令,eip中存放下一条即将执行的指令,当eip中的值被PC取走,eip自动加1,当然,在这个地方,如果有转移指令等eip就不仅是+1咯。

2.2 多任务下:

多任务下就避免不了进程的调度,当一个进程的时间片结束时,此时产生一个系统中断,中断产生之后,cpu和内核保存eip,标志寄存器等到内核栈,即保存现场到该进程自己的内核栈中,操作系统开始进程调度,下一个进程开始执行,将原来的esp,eip,ebp等覆盖。当再次调度到最初的进程的时候,开始从内核栈中恢复各个寄存器等的值(eip,esp...)继续执行。

  

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值