堆栈,我们说它常常用于在一些函数调用、中断及异常处理中,用于保存发生函数调用、中断和异常发生前的现场,待函数调用、中断和异常结束后,用于恢复先前的现场。

比如主程序正在用W0 计算数据,被中断打断了,要执行中断程序,而中断程序里也要使用W0这个寄存器。 这时候就可以先把W0压栈,等中断结束后,再弹栈将W0数据恢复,主程序继续执行。

 任何时候想保存临时数据,都可以使用堆栈。

那么,我们说堆栈的方向有向上生长和向下生长两种,dspace单片机的生长方向是向上生长的,先进后出的原则

如果我们不自己去设置堆栈的空间的话,那么就是使用编译器默认分配的空间。

如何设置一段堆栈空间

堆栈的起始地址我们是需要知道,在dspac单片机中,W15寄存器是被用作堆栈指针的。所以,在我们设置的时候,就需要给W15寄存器给定一个初始地址,作为堆栈空间的起始地址。然后,堆栈空间是不是不能无穷大是吧,是需要有一个范围的是把?所以,我们需要给堆栈空间设置一个大小。在程序写之前,我们谁都不知道多大最合适。
所以,我们开始给一个尽量大一点的空间,不影响我们对RAM的使用就可以了。

基于汇编的嵌入式堆栈

这段代码就是设置堆栈空间的。

基于汇编的嵌入式堆栈

这两段代码合起来就实现了堆栈空间设置功能。

. stack 1050  相当于定义段的起始地址。__SP_init = .;/*-堆栈起始地址为0x1050--*/  然后这里注意一下 = 前后需要有一个空格。不然会报错的。

堆栈设置的区域就是从 0x1050 到 0x10F8。使用w0是为了传递中间设置的数据。

这个地方是设置一个堆栈空间,这个空间的起始地址是0x1050,这句话是把当前地址给到 __SP_init这个变量里面。可以认为它是一个常量,我们现在是在给这个常量赋值。
__SP_init = .;,这个“.”就是1050吗?即 “ .”代表当前地址。

基于汇编的嵌入式堆栈

基于汇编的嵌入式堆栈

它都可以表示当前地址。

W14是作为在堆栈里面又划分了一小段空间来作为临时使用的地址指针。
堆栈设置,为什么放在了数据存储器里面?堆栈是用来保存数据的,保存数据的话都是在RAM里面操作的,那么堆栈空间肯定要设置在RAM里面了。堆栈区域中的数据都是临时数据。也就是说,所以RAM中的数据,都是临时数据,掉电就会消失。

 . += 0x00a8;/*--堆栈大小为168字节---*/ 

 . += 0x00a8;/*--堆栈大小为168字节---*/   ------->    当前地址 = 0x1050 + 0x00a8 = 0x10F8。

 __SPLIM_init = .;  ---->   __SPLIM_init = 0x10F8。

. += 0x0008;  ------> 当前地址 = 0x10F8 + 0x0008。

加个0X0008是留有一个余量,以防溢出之后,我们还有可以挽救的空间。

假设要存放的临时数据太多了,那么是不是可能导致堆栈溢出啊?这里多留一段空间,可以起到缓冲的效果。

基于汇编的嵌入式堆栈

向上生长的一般放在最底部,如果向下生长的,一般放在最顶部。

如果堆栈超出了我们设置的这段空间,那么他会产生一个堆栈错误陷阱。可以编写堆栈错误陷阱服务程序,来做相关处理。

用C的话,可以不用考虑堆栈。

相关文章:

  • 2022-02-03
  • 2021-08-14
  • 2021-11-01
  • 2021-09-21
  • 2021-12-18
  • 2021-05-25
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2021-10-12
  • 2021-09-10
  • 2022-12-23
  • 2021-11-28
  • 2021-11-21
  • 2022-02-14
相关资源
相似解决方案