计算机程序的执行过程分析

《Linux内核分析》课程第一次作业

(曹越+原创作品转载请注明出处+《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000)

程序的正确执行靠堆栈来维持,堆栈是一块保存数据的连续内存。一个名为堆栈指针(ESP)的寄存器指向堆栈的顶部,一个名为堆栈指针(EBP)的寄存器指向堆栈的底部。堆栈的底部在一个固定的地址。堆栈的大小在运行时由内核动态地调整。CPU实现指令PUSH和POP, 向堆栈中添加元素和从中移去元素,而且要注意的是堆栈是向低地址增长的。

下面我们通过一个简单的例子来说明程序是如何执行的:

main.c


为了理解程序在调用时都做了哪些事情, 我们使用gcc的-S选项编译, 以产生汇编代码整理输出:            

main.s:


  

一些汇编代码简单说明  :

(main函数)

  • pushl %ebp 将帧指针ebp压入栈中
  • movl %esp,%ebp 然后把当前的esp复制到ebp, 使其成为新的帧指针
  • subl $4,%esp 将栈顶指针esp的值减4
  • movl $17,(%esp) 指将参数17压入栈
  • call f 先把eip压入栈,在跳转到f处去执行
  • addl $2,%eax 指函数返回值存在寄存器eax中,并对其值加2
  • leave其实是一条宏汇编指令,相当于movl %ebp,%esp、popl %ebp两条指令回收栈空间,然后ebp出栈 
  • ret相当于popl %eip,指令寄存器eip出栈

(f函数)

  • pushl %ebp 将帧指针ebp压入栈中(old-ebp)
  • movl %esp,%ebp 然后把当前的esp复制到ebp, 使其成为新的帧指针
  • subl $4,%esp 将f函数栈顶地址减4
  • movl 8(%ebp),%eax 间接寻址,将ebp寄存器加8的位置里面存放的内容移到eax寄存器中
  • movl %eax,(%esp) 将eax值写入堆栈
  • call g 先把eip压入栈,在跳转到g处去执行
  • leave 相当于movl %ebp,%esp、popl %ebp两条指令回收栈空间,然后ebp出栈
  • ret 指令寄存器eip出栈

(g函数)

  • pushl %ebp 将帧指针ebp压入栈中(old-ebp)
  • movl %esp,%ebp 然后把当前的esp复制到ebp, 使其成为新的帧指针
  • movl 0x8(%ebp),%eax 间接寻址,将ebp寄存器加8的位置里面存放的内容移到eax寄存器中
  • addl $2,%eax 寄存器eax加2
  • popl %ebp 退栈
  • ret 返回

总结:存储程序计算机工作流程就是eip不停地取出指令让cpu去执行,函数的调用通过堆栈来实现。看似一个简单C程序也需要经过编译链接之后才能生成可执行程序,这其间的复杂程度远远超出我们的想象。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值