美文网首页
从C语言中的函数调用过程理解计算机执行原理

从C语言中的函数调用过程理解计算机执行原理

作者: 梅花小筑 | 来源:发表于2016-02-28 00:15 被阅读446次

本文是Mooc <Linxu操作系统分析>课程第一次作业.
姓名:石维康
转载请注明出处.
经过简单的数字修改,需要编译的C语言代码如下:
int g(int x)
{
return x + 2;
}

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

int main(void)
{
return f(5) + 4;
}
编译后生成的汇编代码如下所示:

Screen Shot 2016-02-27 at 8.02.50 PM.png

生成的完整汇编代码如下:

g:
  pushl   %ebp
  movl    %esp, %ebp
  movl    8(%ebp), %eax
  addl    $2, %eax
  popl    %ebp
  ret
f:
  pushl   %ebp
  movl    %esp, %ebp
  subl    $4, %esp
  movl    8(%ebp), %eax
  movl    %eax, (%esp)
  call    g
  leave
  ret
main:
  pushl   %ebp
  movl    %esp, %ebp
  subl    $4, %esp
  movl    $5, (%esp)
  call    f
  addl    $4, %eax
  leave
  ret

完整截图(对应汇编代码函数):

汇编代码

与视频中采用相同约定,假设初始esp= ebp =0.
先进入main函数执行到call f后,esp=3,ebp=1,堆栈目前的情况
              编号   内容
              | --- | --- |
ebp           |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
esp           |  3 |   23 |
              | --- | --- |
              | --- | --- |
              |  4 |      |
              | --- | --- |


进入f函数,执行到call g后,堆栈如下

ebp=4


              | --- | --- |
              |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
              |  3 |   23 |
              | --- | --- |
              | --- | --- |
 ebp->        |  4 |   1  |
              | --- | --- |
              | --- | --- |
              |  5 |   5  |
              | --- | --- |
              | --- | --- |
esp->         |  6 |   14 |
              | --- | --- |


 进入g函数执行运算,执行到addl  $2, %eax 这句. eax=5+2=7



              | --- | --- |
              |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
              |  3 |   23 |
              | --- | --- |
              | --- | --- |
              |  4 |   1  |
              | --- | --- |
              | --- | --- |
              |  5 |   5  |
              | --- | --- |
              | --- | --- |
              |  6 |   15 |
              | --- | --- |
              | --- | --- |
esp,ebp->     |  7  |  4  |
              | --- | --- |

在g函数值中,在eip指向ret语句时(即执行完popl %ebp),堆栈如下:
              | --- | --- |
              |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
              |  3 |   23 |
              | --- | --- |
              | --- | --- |
ebp->         |  4 |   1  |
              | --- | --- |
              | --- | --- |
              |  5 |   5  |
              | --- | --- |
              | --- | --- |
esp->         |  6 |   15 |
              | --- | --- |

ret 后 eip=15,堆栈变成如下:

              | --- | --- |
              |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
              |  3 |   23 |
              | --- | --- |
              | --- | --- |
ebp->         |  4 |   1  |
              | --- | --- |
              | --- | --- |
esp->         |  5 |   5  |
              | --- | --- |

f中的leave执行完之后:

              | --- | --- |
ebp->         |  1 |   0  |
              | --- | --- |
              | --- | --- |
              |  2  |  5  |
              | --- | --- |
              | --- | --- |
esp->         |  3 |   23 |
              | --- | --- |

执行f中的ret后,eip=23,eax=7:
              | --- | --- |
ebp->         |  1 |   0  |
              | --- | --- |
              | --- | --- |
esp->         |  2  |  5  |
              | --- | --- |
执行main中的leave后,堆栈如下,eax=11,esp=ebp=0:
ebp,esp->     | --- | --- |
              |  1 |   0  |
              | --- | --- |

回到初始态.

我对计算机执行程序的理解:
计算机只是机械的从PC指针指向的位置取指令并解析执行.而数据与指令都是以二进制形式进行存储.
在C语言层面上的函数调用与返回的语义,在x86层面上是通过call指令与ret指令来完成.

相关文章

  • 从C语言中的函数调用过程理解计算机执行原理

    本文是Mooc 课程第一次作业.姓名:石维康转载请注明出处.经过简单的数字修改,需要编译的C语言代码如下:int...

  • 3-协程

    协程概念 子程序/函数:在所有语言中都是层级调用,比如A调用B,在B执行的过程中又可以调用C,C执行完毕返回,B执...

  • 什么是协程

    什么是协程 子程序, 或者称为函数, 在所有语言中都是层级调用, 比如A调用B, B在执行过程中又调用了C, C执...

  • 精解C语言函数

    C语言中的函数在其他编程语言中也称为过程或子程序。要执行任务,我们可以创建函数。一个函数可以被多次调用。 它提供了...

  • day 6

    5 函数的调用过程 在c语言中不允许函数嵌套 6 函数的声明与常见终端命令 函数需要先声明再调用,也就是说c语言中...

  • 【iOS小结】Runtime

    一.Runtime简介 C语言中,在编译期,函数的调用就会决定调用哪个函数。而OC的函数,属于动态调用过程,在编译...

  • 语言基础

    1. 函数调用 函数是Go语言中的一等公民。从函数的调用惯例和参数的传递方法两方面分别介绍函数的执行过程。 1.1...

  • [转载]C语言函数调用栈

    原文地址:C语言函数调用栈(一)C语言函数调用栈(二) 0 引言 程序的执行过程可看作连续的函数调用。当一个函数执...

  • Runtime之消息发送

    调用对象的方法,在Objective-C中叫做传递消息,先来看一下C语言中的函数调用方式 C语言中的函数调用方式 ...

  • Runtime

    C语言中,在编译期,函数的调用就会决定调用哪个函数,而OC的函数,属于动态调用过程,在编译期并不能决定真正调用哪个...

网友评论

      本文标题:从C语言中的函数调用过程理解计算机执行原理

      本文链接:https://www.haomeiwen.com/subject/xoiwkttx.html