CodeWarrior自动生成的工程中堆栈指针的初始化机制
打开CodeWarrior中的一个新建工程,在Start12.c文件中可以看到语句
“INIT_SP_FROM_STARTUP_DESC()”,
这是系统自动生成对堆栈指针的初始化语句。这条语句是个宏函数,具体为
#define INIT_SP_FROM_STARTUP_DESC() __asm LDS #__SEG_END_SSTACK;
其中__SEG_END_SSTACK是由编译器根据配置文件自动生成的,从而达到按照用户要求配置堆栈指针的目的。
几种不同的堆栈的内存分布及配置方法
1.RAM区的开始是堆栈区,随后是数据区,示意图如下。
___________________
|堆栈区 |数据区 |未使用区|
|_____|______|______|
|
SP
这时堆栈区的大小由prm文件中STACKSIZE参数指定,而SP的具体值由编译器根据指定的堆栈区大小计算得出。
这个内存分布是新建工程的默认配置,是由prm文件中PLACEMENT区语句:
“SSTACK, DEFAULT_RAM INTO RAM;”
决定的。当把语句换成:
“DEFAULT_RAM, SSTACK INTO RAM;”
时,RAM区的分布会变为开始是数据区,随后才是堆栈区。
而且,当不指定SSTACK在内存中分布时,即语句变为:
“DEFAULT_RAM INTO RAM;”
时,RAM区的分布也会变为开始是数据区,随后才是堆栈区
示意图如下:
___________________
|数据区 |堆栈区 |未使用区|
|_____|______|______|
|
SP
2.堆栈区在RAM区任意位置,示意图如下。
___________________________
|数据区 |未使用区 |堆栈区| 未使用区|
|_____|_______|_____|_______|
|
SP
实现这种分布有两种方法,
第一种:利用prm文件
这时SP的值由prm文件中STACKTOP参数指定(自动生成的工程中没有此参数,需要用户自己添加),堆栈区的大小也需要在prm文件中自己指定,例子如下:
SEGMENTS
MY_STK = NO_INIT 0xB00 TO 0xBFF;
MY_RAM = READ_WRITE 0xA00 TO 0xAFF;
MY_ROM = READ_ONLY 0x800 TO 0x9FF;
END
PLACEMENT
DEFAULT_ROM INTO MY_ROM;
DEFAULT_RAM INTO MY_RAM;
SSTACK INTO MY_STK;
END
STACKTOP 0xB7E
本例中堆栈区大小为从0xB7E到0xB00,SP的值为0xB7E。
注:在并不关注堆栈区的位置而仅仅关注堆栈区大小的情况下,CodeWarrior推荐用STACKSIZE的方式定义堆栈,即此时不推荐用STACKTOP的方式。
第二种,在start12.c文件中自己指定
在函数_Startup的开始用语句:
__asm LDS #VAR;(VAR为自己指定的SP的值)
来指定SP的值,堆栈区的大小由prm文件中STACKSIZE参数指定。
打开CodeWarrior中的一个新建工程,在Start12.c文件中可以看到语句
“INIT_SP_FROM_STARTUP_DESC()”,
这是系统自动生成对堆栈指针的初始化语句。这条语句是个宏函数,具体为
#define INIT_SP_FROM_STARTUP_DESC() __asm LDS #__SEG_END_SSTACK;
其中__SEG_END_SSTACK是由编译器根据配置文件自动生成的,从而达到按照用户要求配置堆栈指针的目的。
几种不同的堆栈的内存分布及配置方法
1.RAM区的开始是堆栈区,随后是数据区,示意图如下。
|堆栈区 |数据区 |未使用区|
|_____|______|______|
这时堆栈区的大小由prm文件中STACKSIZE参数指定,而SP的具体值由编译器根据指定的堆栈区大小计算得出。
这个内存分布是新建工程的默认配置,是由prm文件中PLACEMENT区语句:
“SSTACK, DEFAULT_RAM INTO RAM;”
决定的。当把语句换成:
“DEFAULT_RAM, SSTACK INTO RAM;”
时,RAM区的分布会变为开始是数据区,随后才是堆栈区。
而且,当不指定SSTACK在内存中分布时,即语句变为:
“DEFAULT_RAM INTO RAM;”
时,RAM区的分布也会变为开始是数据区,随后才是堆栈区
示意图如下:
|数据区 |堆栈区 |未使用区|
|_____|______|______|
2.堆栈区在RAM区任意位置,示意图如下。
|数据区 |未使用区 |堆栈区| 未使用区|
|_____|_______|_____|_______|
实现这种分布有两种方法,
第一种:利用prm文件
这时SP的值由prm文件中STACKTOP参数指定(自动生成的工程中没有此参数,需要用户自己添加),堆栈区的大小也需要在prm文件中自己指定,例子如下:
SEGMENTS
MY_STK = NO_INIT 0xB00 TO 0xBFF;
MY_RAM = READ_WRITE 0xA00 TO 0xAFF;
MY_ROM = READ_ONLY 0x800 TO 0x9FF;
END
PLACEMENT
DEFAULT_ROM INTO MY_ROM;
DEFAULT_RAM INTO MY_RAM;
SSTACK INTO MY_STK;
END
STACKTOP 0xB7E
本例中堆栈区大小为从0xB7E到0xB00,SP的值为0xB7E。
注:在并不关注堆栈区的位置而仅仅关注堆栈区大小的情况下,CodeWarrior推荐用STACKSIZE的方式定义堆栈,即此时不推荐用STACKTOP的方式。
第二种,在start12.c文件中自己指定
在函数_Startup的开始用语句:
__asm LDS #VAR;(VAR为自己指定的SP的值)
来指定SP的值,堆栈区的大小由prm文件中STACKSIZE参数指定。