【摘要】:C编译器使用软件堆栈来进行如下操作:●分配自动变量。编译器使用以下两个工作寄存器来管理堆栈:●W15:堆栈指针,指向栈顶,栈顶定义为堆栈的第一个未使用单元。如果堆栈超出堆栈指针限制寄存器中的值,将转入堆栈错误陷阱。用户可以通过初始化堆栈指针限制寄存器来进一步限制堆栈的增长。执行CALL或RCALL指令将返回地址压入软件堆栈。图2-6 将被调用函数保存的寄存器弹出堆栈
●分配自动变量。
●传递函数参数。
●在中断函数中保存处理器状态。
●保存函数返回地址。
●存储临时变量。
●函数调用时保护寄存器。
运行时堆栈是向上增长的,即从低地址向高地址增长。编译器使用以下两个工作寄存器来管理堆栈(见图2-3):
●W15:堆栈指针,指向栈顶,栈顶定义为堆栈的第一个未使用单元。
●W14:帧指针(Frame Pointer,FP),指向当前函数的帧。如果需要,每个函数都会在栈顶创建一个新的帧来分配自动变量和临时变量。可使用编译器选项-fomit-frame-pointer来限制帧指针的使用。
图2-3 堆栈指针和帧指针(www.xing528.com)
C运行时启动模块(libpic30.a中的crt0.o和crt1.o)初始化堆栈指针(W15),使其指向栈底,初始化堆栈指针限制寄存器使其指向栈顶。如果堆栈超出堆栈指针限制寄存器中的值,将转入堆栈错误陷阱。用户可以通过初始化堆栈指针限制寄存器来进一步限制堆栈的增长。
图2-4说明了调用一个函数的步骤。执行CALL或RCALL指令将返回地址压入软件堆栈。
现在被调用函数可以为其局部现场分配空间了,如图2-5所示。
图2-4 CALL或RCALL指令
图2-5 被调用函数的空间分配
最后,函数中用到的所有被调用函数保存寄存器被压入堆栈,如图2-6所示。
图2-6 将被调用函数保存的寄存器弹出堆栈
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。