linux 反汇编代码程序,通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的...

计算机是如何工作的

我们平时使用的计算机属于“冯·诺依曼结构计算机”,这种计算机将程序存储在内存中,CPU从内存中不断地取指令并执行指令。CPU能够执行的指令是二进制指令,为了便于理解,人们发明了汇编指令,它是对机器指令的简单翻译,但是增强了可读性。我们平时所使用的编程语言多属于高级语言,它具有良好的可读性,却不能被计算机直接执行,因此,高级语言通常都要经过编译或解释说明等过程,转换为计算机能够执行的机器语言。下面我们以一个简单的C程序为例,分析计算机如何执行指令。

C程序代码参考截图一。将其命名为main.c,然后执行一条命令生成对应的汇编代码:

gcc -S -o main.s main.c -m32

其中-S选项表示在生成汇编代码后停止编译过程,-o选项表示输出编译结果,即输出汇编代码至main.s文件中,-m32则表示生成32位的汇编代码。

生成的main.s文件较复杂,我们把其中以句点"."开始的行全部删去,这些行是链接文件时需要使用的,与程序本身关系不大。留下的汇编代码就是C程序转换后获得的代码了,参考截图二。可以看到汇编代码中也有三个函数,分别对应于C代码中的main(), f(), g()函数。

要说明汇编语言的执行过程,还需要引入另外一个重要的计算机概念——栈。它是一个“先进后出”的数据结构,栈底由寄存器ebp指示,栈顶由寄存器esp指示,栈在内存中向下增长,即每压入一个元素,esp的值减小,每弹出一个元素,esp的值增大。

现在我们来分析汇编代码的执行过程,不妨假设程序开始时esp和ebp两个寄存器指向同一初始位置,以序号0表示,序号延栈增长的方向增大,即压入一个元素后esp指向位置1,弹出一个元素后esp指向位置0,以此类推。要注意相邻两个序号的物理地址相差4而不是相差1。

pushl %ebp

esp的值首先减4,然后将ebp的值存储在esp指示的位置,则栈中序号为1的位置存储了ebp的当前值(0),ebp仍指向位置0,esp指向位置1;

movl %esp, %ebp

此时ebp与esp都指向位置1;

subl $4, %esp

esp指向位置2;

movl $12, (%esp)

栈的位置2存储立即数12;

call f

首先将eip压入栈中,eip此时的值是下一条将要执行的指令的位置,我们不妨以行号代表,即将行号23存入栈中位置3,此时esp指向位置3,ebp指向位置1;然后将函数f的起始位置赋给寄存器eip,即下一条指令为f的第一条指令;

pushl %ebp

栈中位置4存储ebp的值(位置1),esp指向位置4;

movl %esp, %ebp

esp和ebp都指向位置4;

subl $4, %esp

esp指向位置5;

movl 8(%ebp), %eax

将ebp之前两个位置处的值给寄存器eax,即将位置2处存储的值12给eax;

movl %eax, (%esp)

将eax中的值存储到esp指向的位置,即栈中位置5存储12;

call g

首先将eip压入栈中,即将行号15存入栈中位置6,此时esp指向位置6,ebp指向位置4;然后将函数g的起始位置赋给寄存器eip,即下一条指令为g的第一条指令;

pushl %ebp

栈中位置7存储ebp的值(位置4),esp指向位置7;

movl %esp, %ebp

esp和ebp都指向位置7;

movl 8(%ebp), %eax

将ebp之前两个位置处的值给寄存器eax,即将位置5处存储的值12给eax;

addl $6, %eax

eax中的值加上6,变为18;

popl %ebp

将栈顶数据弹出到ebp中,即将栈中位置7的值“位置4”赋给ebp,同时esp指向位置6;

ret

将栈顶数据弹出到eip中,即将栈中位置6的值“行15”赋给eip,同时esp指向位置5,下一条指令变为第15行处的指令;

leave

这条指令首先将ebp的值赋给esp,即esp和ebp都指向位置4,然后将栈顶元素弹出到ebp中,即将栈中位置4的值“位置1”赋给ebp,同时esp指向位置3;

ret

将栈顶数据弹出到eip中,即将栈中位置3的值“行23”赋给eip,同时esp指向位置2,下一条指令变为第23行处的指令;

addl $1, %eax

将寄存器eax中的值加1,变为19;

leave

首先将ebp的值赋给esp,即esp和ebp都指向位置1,然后将栈顶元素弹出到ebp中,即将栈中位置4的值“位置0”赋给ebp,同时esp指向位置0;

ret

将栈顶数据弹出到eip中,即将栈中位置0的值赋给eip,同时esp指向位置-1,下一条指令变为程序开始前的指令。

总结

以上我们逐条分析了汇编程序的运行过程,尤其是栈的变化情况。通过这种分析我们可以看到计算机运行的基本机制:计算机将编辑好的程序存储与内存中,然后逐条执行程序代码,利用寄存器和栈结构来存储中间结果,直至程序执行完毕。

pfqDLptbtHqGXucdao1ypbZqeFOxwnTmzhFbS6cE-wm

SuHBKtWdjQhwGQztXGhvzqc5WJD1gZhpBYk4JVvx-wm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值