当前位置:首页 > 单片机 > 单片机
[导读]我们知道C语言是一种高级语言,所谓高级语言就是要经过翻译才能在具体平台上运行的程序。而编译程序是一种比较繁琐的程序,它要把高级语言编译和链接后,成为能够在具体平台运行的程序。这其中有很多知识是和操作系统

我们知道C语言是一种高级语言,所谓高级语言就是要经过翻译才能在具体平台上运行的程序。而编译程序是一种比较繁琐的程序,它要把高级语言编译和链接后,成为能够在具体平台运行的程序。这其中有很多知识是和操作系统和具体硬件平台相关的,如果你想弄清楚编译程序请学习编译原理,有一本书可以参考《linkers_and_loaders》。

我们这里只是说明一下C语言运行的环境以及和栈的关系。让我们从汇编语言和底层硬件来了解C语言的一些概念和C语言是如何利用栈来进控制过程调用的。

先讲一下栈:

栈是这样一种结构:本事是一段连续的内存空间,怎么使用这样一种内存空间才算是起到了栈的实际作用那,首先要规定这一段连续空间的基地址,然后就从这个地址开始依次放东西。取东西时也是从最上面的开始取。按照上面的方案管理这一段存储空间,就是发挥了栈的作用。因为栈使用的频率实在是太高了,所以在计算机汇编层次就有专门操作栈的指令。包括push(入栈)、pop(出栈)等。

其实栈又有一些逻辑上的分类:

根据先腾出空间再用还是先用再腾空间分为:

1,满堆栈:即入栈后堆栈指针sp指向最后一个入栈的元素。也就是sp先减一(加一)再入栈。

2,空堆栈:即入栈后堆栈指针指向最后一个入栈元素的下一个元素。也就是先入栈sp再减一(或加一)。

根据从高地址开始用还是从低地址开始用分为:

1,递增堆栈:即堆栈一开始的地址是低地址,向高地址开始递增。就如同一个水杯(假设上面地址大)开口的是大地址,从杯底开始装水。自己画一画图就清楚了。我就偷懒一下不画了。

2,递减堆栈:即堆栈一开始的地址是高地址,向低地址开始递增。就如同还是刚才说的那个水杯,现在开口的是小地址,从大地址开始用,往下走,相当于杯子口朝下。我们用的时候是把水往上一点点压上去。呵呵呵,不过这样的杯子就失去了用途。但在内存上还是可以的。

那么根据这两种分类方法,我们就可以得到四种栈的类型,而ARM920T中使用的是递减满堆栈。

下面重点说明c语言运行时是怎么用栈来控制函数调用过程的。

大家想一想,我们写c语言时用到函数调用,有时候还嵌套调用很多函数。还有有些函数还需要参数和返回值。怎么处理各个函数的参数和返回值,以及当每一个函数完成工作时该返回到那个地方。这些都是要解决的问题。当然最容易想到的也是必须做的是在进行调用跳转之前,把我这个函数现有的状态保存起来,保存什么那,调用函数返回后的下一条指令,还有我这个函数需要的哪些数据。还有就是保存这些信息到哪些地方哪?这些都是我们要解决的问题。还有就是你不光要保存这些信息,还要保存这些信息的顺序。因为函数调用本身有顺序,你像a调用b,b又接着调用c。在c执行完后要返回到b,b执行完再返回a。呵呵,有顺序。

我们一一想办法来解决,当然别人已经用栈的策略解决的很完美了,我们只是想一些更简洁的最容易想起来的但是不完善的方法,也正说明了人家的策略是多么的优秀。

关于调用函数的问题,我们可以把返回地址保存到一些地方,当然程序员知道在那?还知道顺序,再根据顺序返回就好了,但做这样的工作太累了,除了写程序还要记这些东西。哎肯定不好也不这样做。关于传参,有这样可以考虑的,用专门规定好的寄存器来做传参。行,但有缺陷,如果传的参数很多或者是变化的,就不好用寄存器传参了。而且我们有操作系统时往往要求编译器产生的代码具有可重入性,也就是保证代码和数据的相对独立性。一个函数被调用两次,都有两次的参数环境。到底现在我们是怎么做的那。答案是用栈。

怎么用,嘻嘻,下面一一道来:

函数在执行一个函数调用调用时,用栈不仅保存函数的返回地址,并且一起把函数所需要的参数和返回值都保存在堆栈中。

也就是每一个函数都有一个这样的栈,保存着一些信息。先说一下栈帧的概念,在函数调用过程中要保存的整个参数集合,包括返回地址称作一个栈帧。

如上图所示,我们以这个图为例,分析一下栈在函数调用中的应用。函数p有两个参数 x1、x2,函数p 调用函数q ,且有两个参数。储存在栈帧的第一帧是上一个栈帧的地址,当前栈帧的地址就是正在使用的栈帧的基值,使用这个指针能方便的找到函数所需的变量和参数等。那为什么每一针的第一个地址要保存上一个栈帧的地址那,和保存返回地址一个初衷,当你当前用的栈帧用完时,把在当前栈帧保存的上一个栈帧的地址取出就还原了上一个栈帧。

接着是返回地址,如果函数有返回值的话,返回值放在返回地址的下面。接着为函数所需要的变量申请空间。

下面说说函数p调用函数q时的具体情况。当执行call q(y1)时,会为函数q创建一个新的栈帧,具体过程是:先保存丄一帧的地址,如果有返回值的话为返回值分配存储空间,然后保存返回地址。然后为y1分配空间并把它初始化为调用q时给的参数。接着分配另一个参数的空间y2,这个参数用于在函数内部计算。

在任何状态下,都有一个当前栈帧的指针fp,这个指针用来保存当前栈帧的地址,那这个值怎么保证是当前的那,先说q函数的吧,是把栈的指针sp先保存下来,然后接着保存fp。然后把fp的值改为sp-4 ,因为我们知道每个栈帧的第一个要保存的是fp。

其实整个过程是动态的,所谓我说是动态的是因为sp指针一直是快速移动的。所以要在每一帧开始的时候先把这个sp保存住。然后往减4的地址处放fp。当这个栈帧全弹出时,就把你保存的fp又恢复到原来你保存的fp了。就一直有fp代表当前栈帧底部。也是唯一一个不变的基地址,用它来找其他的变量。

好了,下面我们看一个在ARM下C语言写的程序然后编译成汇编语言分析其栈的应用。(在linux2.4内核下写的c语言程序,用arm-linux-gcc3.4.1编译器编译)

C语言源程序如下:

#include

int max(int,int);

int main(int argc,char *argv[])

{

int a=3,b=5;

max(a,b);

return 0;

}

int max(int x,int y)

{

if(x>y)

return x;

else

return y

}

函数很简单,在主函数里调用一个外部函数max用于两个数中数值较大的那个数并返回。

下面看ARM的汇编是怎么实现的这些功能,以及这中间栈的使用情况。

.file "max.c"

.text

.align 2

.global main

.type main, %function

main:

@ args = 0, pretend = 0, frame = 16

@ frame_needed = 1, uses_anonymous_args = 0

mov ip, sp

stmfd sp!, {fp, ip, lr, pc}

sub fp, ip, #4

sub sp, sp, #16

str r0, [fp, #-16]

str r1, [fp, #-20]

mov r3, #3

str r3, [fp, #-24]

mov r3, #5

str r3, [fp, #-28]

ldr r0, [fp, #-24]

ldr r1, [fp, #-28]

bl max //开始调用max函数

mov r3, #0

mov r0, r3

sub sp, fp, #12

ldmfd sp, {fp, sp, pc}

.size main, .-main

.align 2

.global max

.type max, %function

max:

@ args = 0, pretend = 0, frame = 12

@ frame_needed = 1, uses_anonymous_args = 0

mov ip, sp

stmfd sp!, {fp, ip, lr, pc}

sub fp, ip, #4

sub sp, sp, #12

str r0, [fp, #-16]

str r1, [fp, #-20]

ldr r2, [fp, #-16]

ldr r3, [fp, #-20]

cmp r2, r3

ble .L3

ldr r3, [fp, #-16]

str

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭