您的位置 首页 芯闻

带你了解嵌入式C言语函数调用栈

带你了解嵌入式C语言函数调用栈-大家都知道函数调用是通过栈来实现的,而且知道在栈中存放着该函数的局部变量。但是对于栈的实现细节可能不一定清楚。

咱们都知道函数调用是经过栈来完结的,并且知道在栈中存放着该函数的局部变量。可是关于栈的完结细节或许不一定清楚。本文将介绍一下在Linux平台下函数栈是怎么完结的。有些同学或许觉得没必要了解这么深化,其实非也。依据本号多年的经历,了解体系深层次的原理对剖析疑难问题有很好的协助。

就像了解抓包是处理网络通信问题的高档兵器相同,了解函数调用栈则是剖析程序内存问题的高档兵器。本文以Linux 64位操作体系下C言语开发为例,介绍应用程序调用栈的完结原理,并经过一个实例和GDB东西详细剖析一下某个程序的调用栈内容。在介绍详细的调用栈之前,咱们先介绍一些根底常识,这些常识是了解后续函数调用栈的根底。

咱们知道IntelCPU在规划的时分都是向前兼容的,也便是在新一代的CPU上能够运转老一代CPU上的编译的程序。为了确保兼容性,新一代CPU保存了老一代寄存器的别号。以16位寄存器AX为例,AL表明低8位,AH表明高8位。而32位CPU面世之后,经过名为EAX的寄存器表明32位寄存器,AX依然保存。以此类推,RAX表明一个64位寄存器。

为了了解函数调用栈的细节,有必要了解一下汇编程序中函数调用的完结。函数的调用首要分为2部分,一个是调用,别的一个是回来。在汇编言语中函数调用是经过call指令完结的,回来则是经过ret指令。

汇编言语的call指令相当于履行了2步操作,分别是,1)将当时的IP或CS和IP压入栈中; 2)跳转,相似与jmp指令。相同,ret指令也分2步,分别是,1)将栈中的地址弹出到IP寄存器;2)跳转履行后续指令。这个基本上便是函数调用的原理。

带你了解嵌入式C言语函数调用栈

除了在代码间的跳动外,函数的调用往往还需求传递一个参数,而处理完结后还或许有回来值。这些数据的传递都是经过寄存器进行的。在函数调用之前经过上文介绍的寄存器存储参数,函数回来之前经过RAX寄存器(32位体系为EAX)存储回来成果。

别的一个比较重要的常识点是函数调用进程中与仓库相关的寄存器RSP和RBP,两个寄存器首要完结对栈方位的记载,详细效果如下:RSP:栈指针寄存器(reextended stack pointer),其内存放着一个指针,该指针永久指向体系栈最上面一个栈帧的栈顶。RBP:基址指针寄存器(reextended base pointer),其内存放着一个指针,该指针永久指向体系栈最上面一个栈帧的底部。

寄存器的称号跟体系结构是相关的,本文是64位体系,因而寄存器是RSP和RBP。如果是32位体系则寄存器的称号为ESP和EBP。

咱们先从全体上来看一下函数调用栈的首要内容,如图4所示。在函数栈中首要包含函数参数表、局部变量表、栈的基址和函数回来地址。这儿栈的基址是上一个栈帧的基址,由于在本函数中需求运用该基址拜访栈中的内容,因而需求首要将上一个栈帧中的基址压栈。

为了便于了解,咱们以一个详细的程序作为示例。本程序十分简略,首要是模仿了多个函数的函数调用联系和参数传递。别的,在函数func_2中界说了2个形参,以模仿多参数传递的进程。

在本示例中,main函数调用func_1函数。咱们从main函数开端剖析,能够先看一下右侧的C言语代码。首要是函数参数的预备进程。在main函数调用func_1时顺次传入的参数为1、2、3和4+g,其间最终一个参数是需求核算的。依照赤色方框的虚线,咱们能够看到对应的汇编程序,在汇编程序中首要处理最终一个参数,然后是倒数第二个,以此类推(函数参数的处理次序在日常开发中是需求留意的内容要点)。一起,咱们看到存储参数的寄存器称号与前文是共同。

当预备完参数之后,便是调用func_1函数,这个在汇编言语中便是call func_1这一行。尽管仅仅一行汇编指令,但其实内部做了一些工作,这个咱们在前文介绍call指令的时分有所介绍,咱们能够参阅一下前文。

之后就进入func_1函数的处理逻辑。最一开端是pushq %rbp汇编程序,这句指令的效果是将RBP压入函数栈中。这句压栈及后边的更新RBP的值(moveq %rsp, %rbp)是构建本函数的栈帧头,后续对本栈帧的内容的拜访都是经过帧头(RBP)进行的。接下来是对参数压栈的进程和局部变量初始化的进程,详细散布参阅图5中的绿色方框和赤色方框。

这样,函数回来后寄存器RBP和RSP从被调用者的栈帧切换到了调用者的栈帧。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/news/xinwen/98474.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部