原创 ADS下C语言中局部变量的存储位置分配

2008-8-21 18:16 4387 5 6 分类: 软件与OS

做研发很多年了,起初开发的软件都是在台式机上运行的,台式机上丰富的资源从来没让我仔细的思考过有关变量的分配问题。做嵌入式系统的开发是最近两年的事儿,最近系统总是出现莫名其妙的错误,开始关注有关堆栈溢出的问题,特意考察一下ADS下C语言局部变量的分配问题。


按照一般教科书上的说法,C语言中的局部变量应该是分配在"栈"中的。而实际情况,有些出入,看看我下面的调试纪录,肯能更容易理解。


这是我写的一段代码,唯一的用途,就是分配变量。

int func1(void)
{
volatile int father;
volatile int mother;
volatile int boy;
volatile int girl;
father = 30;
mother = boy = girl = father;
return father;
}
int func2(void)
{
volatile int father;
volatile int mother;
volatile int boy;
volatile int girl;
volatile int unnecessary;
father = 30;
mother = boy = girl = father;
unnecessary = 0;
return father;
}
int func3(void)
{
volatile int stone[2];
stone[0] = 30;
return stone[0];
}
int func4(void)
{
volatile int stone[2];
stone[0] = 30;
if(stone[0] == 30)
{
volatile int father;
father = 91;
}
else
{
volatile int mother;
mother = 90;
}
return stone[0];
}
int func5(void)
{
volatile int stone[2];
stone[0] = 30;
if(stone[0] == 30)
{
volatile int boy[2];
boy[0] = 91;
}
else
{
volatile int girl[2];
girl[0] = 90;
}
return stone[0];
}
int func10(int a, int b, int c, int d)
{
return a + b + c + d;
}
int func11(int a, int b, int c, int d)
{
volatile int father = a;
volatile int mother = b;
volatile int boy = c;
volatile int girl = d;
return father + mother + boy + girl;
}
typedef struct Home
{
int father;
int mother;
} THome;
int func12()
{
THome home;
home.father= 12;
home.mother = 12;
return home.father + home.mother;
}
typedef int uint32;
int func13()
{
uint32 home = 2;
home *= 2;
return home;
}
int main(void)
{
func1();
func2();
func3();
func4();
func5();

func10(1,2,3,4);
func11(1,2,3,4);
func12();
func13();
}


通常,ADS编译的代码使用R13作为堆栈指针,也就是SP。


先看看刚进入main()函数的时候,R13=0x08000000。


77.aspx


单步执行一步后,R13=0x07FFFFC。减少了4字节,PC入栈引起。


78.aspx


进入fun1()后,R13=0x07FFFFC。没有变化,说明这几个变量没有入栈,实际上他们分别分配在R0-R3。


79.aspx


进入fun2()后,R13=0x07FFFF8。比0x07FFFFC少4字节,前4个仍然分配在R0-R3,第5个变量入栈。


80.aspx


进入fun3()后,R13=0x07FFFF0。比0x07FFFFC少12字节,除了数组入栈外,还有PC。


81.aspx


进入fun4()后,R13=0x07FFFF0。跟func4()一样,数组和PC入栈,分支中的变量放在R0中。


82.aspx


进入fun5()后,R13=0x07FFFE8。比fun4()少8字节,说明分支中的数组也入栈了。


83.aspx


进入fun10()后,R13=0x07FFFFC。4个函数形参也是分配在R0-R3。


84.aspx


进入fun11()后,R13=0x07FFFEC。比0x07FFFFC少16字节,4个形参仍然分配在R0-R3,另外4个变量入栈。


85.aspx


进入fun12()后,R13=0x07FFFF0。跟func4()一样,结构体变量也是入栈的。


86.aspx


进入fun13()后,R13=0x07FFFFC。没有变化,char、int这些变量即使经过typedef,其处理方法仍然不变。


87.aspx

文章评论2条评论)

登录后参与讨论

walnutcy_696810119 2008-8-24 23:55

因为我与这个网站交换过链接,会经常去看看... 呵呵,

walnutcy_696810119 2008-8-24 23:53

这个不是原创的吧?? 别人8.12号就发布了,这边是8.21号. <窗户纸>里的东西, http://www.getproject.com.cn/Article/Show/117.aspx
相关推荐阅读
用户461316 2009-08-17 17:57
Zigbee星型网络组网程序段
最近一直在做Zigbee的星型网络的组网试验,由于时间的原因,现在只是在最高的应用层上来编写程序。即协议栈的程序是2430的开发商(无限龙)编写的,我只是调用相应的函数来完成组网的,星型网络组网部分的...
用户461316 2009-08-17 17:14
VB6的标题栏使用上真彩色图标
模块 ModIcon.Bas 代码: Option Explicit Private Declare Function DrawIcon Lib "user32" (ByVal hdc As Long...
用户461316 2009-08-17 16:58
AppendToLog一个API方式存取日志文件的模块
'**************************************' 模块名称: AppendToLog' 功能描述:一个很不错的日志文件写入模块,不同于'     open/print/...
用户461316 2009-08-17 16:57
(VB自定义函数)去除字符串中的空格
'去除字符串中的空格(方法一)Public Function DelBlank(SearchString As String)   DelBlank = Replace(SearchString, C...
用户461316 2009-08-17 16:56
(VB自定义函数)对任意输入的汉字,可以得到它的拼音的第一个字母
调用方法:Command1.Caption = getHzPy("你")'//函数入口为汉字串,返回值为该汉字的第一个字母Public Function getHzPy(hzStr As String...
用户461316 2009-08-17 16:54
VB_代码执行速度测试
'**************************************'Windows API/Global Declarations for :[ '     A Simple] code ...
我要评论
2
5
关闭 站长推荐上一条 /2 下一条