28335汇编语言与c函数调用,汇编 函数调用的实现

1. 从代码的顺序执行说起

每一个程序员脑子里应该都有这么一种印象:“程序是顺序执行的”。这个观点其实和我们开篇所讲的cpu的流水线执行过程直接相关。

让我们再回忆一下脑海中关于函数调用的概念,也许会是这个样子:

6c2698ee89e29e8ad86bf8b191e3243b.png

这里的“控制流转移”又是如何发生的呢?在解释这个之前,也许我们需要科普一点有关于汇编的知识。

2. 函数调用中的一些细节说明

2.1 函数调用中的关键寄存器

2.1.1 程序计数器PC

程序计数器是一个计算机组成原理中讲过的概念,下面给出一个百度百科中的简单解释

程序计数器是用于存放下一条指令所在单元的地址的地方。

当执行一条指令时,首先需要根据PC中存放的指令地址,将指令由内存取到指令寄存器中,此过程称为“取指令”。与此同时,PC中的地址或自动加1或由转移指针给出下一条指令的地址。此后经过分析指令,执行指令。完成第一条指令的执行,而后根据PC取出第二条指令的地址,如此循环,执行每一条指令。

可以看到,程序计数器是一个cpu执行指令代码过程中的关键寄存器:它指向了当前计算机要执行的指令地址,CPU总是从程序计数器取出当前指令来执行。当指令执行后,程序计数器的值自动增加,指向下一条将要执行的指令。

在x86汇编中,执行程序计数器功能的寄存器被叫做EIP,也叫作指令指针寄存器。

2.1.2 基址指针,栈指针和程序栈

栈是程序设计中的一种经典数据结构,每个程序都拥有自己的程序栈。很重要的一点是,栈是向下生长的。所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低。对x86体系的CPU而言,其中

—> 寄存器ebp(base pointer )可称为“帧指针”或“基址指针”,其实语意是相同的。

—> 寄存器esp(stack pointer)可称为“ 栈指针”。

在C和C++语言中,临时变量分配在栈中,临时变量拥有函数级的生命周期,即“在当前函数中有效,在函数外无效”。这种现象就是函数调用过程中的参数压栈,堆栈平衡所带来的。对于这种实现的细节,我们会在接下来的环节中详细讨论。

2.2. 堆栈平衡

堆栈平衡这个概念指的是函数调完成后,要返还所有使用过的栈空间。这种说法可能有点抽象,我们可以举一个简单的例子来类比:

我们都知道函数的临时变量存放在栈中。那我们来看下面的代码,它是一个很简单的函数,用来交换传入的2个参数的值:

void __stdcall swap(int& a,int& b)

{

int c = a;

a = b;

b = c;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值