提示:本文内容参考慕课课程:《ARM微控制器与嵌入式系统》
文章目录
一、堆栈Stack
1.堆栈的概念
堆栈是一段连续的存储器空间,堆栈按照后入先出的方式工作(Last In First Out),只能向/从堆栈的顶部加入或取出数据,即堆栈能够保持数据的顺序。
• 堆:是一个进程开启以后,系统分配给它的间,一般这个空间是全局的,系统中所有动态分配的对象(比如指针)都是在这个空间上分配。堆里的数据是有数据结构的,其空间占用是不连续的。在没有OS的嵌入式系统中,通常不使用堆。
• 栈:是一个线程维护的一个先进后出的数据构,主要用于静态变量的分配及维护程序各个函数调用时使用。栈里的内容是没有数据结构的,其空间占用是连续的。栈是微处理器的必要特性,是支持高级语言编程的前提。
堆栈有两种基本的操作方式:
推入PUSH: 将内容加入到堆栈顶端
取出PULL : 将堆栈顶端的内容取出
对于大多数CPU而言,“顶端”是指
低位的地址空间
2.堆栈的作用
• 汇编程序可以使用堆栈来保存局部变量,寄存器值。
• C语言编译器使用堆栈来完成参数传递和返回值传递 →C语言的函数调
• CPU硬件 使用堆栈来保存返回地址和寄存器上下文(register context) →中断
3.堆栈指针寄存器Stack Pointer
1.堆栈顶端位置通过CPU内的堆栈指针寄存器确定(SP,Stack Pointer)。
2.堆栈指针的初始位置由程序代码确定,指向预先划定的堆
栈空间的底部
3.如果要自己操作堆栈,记住:
· Once push must pull
· Last In First Out
在使用C语言时,我们对于堆栈的绝大多数使用是感觉不到的,因为C语言的函数调用,函数的返回值,参数传递,局部变量的开销都是由编译器帮我们隐性的使用了堆栈。
开发工具会写出代码初始化堆栈,C语言编译器会隐性使用堆栈,用汇编编写中断时,需要注意堆栈。
4.举例
先了解一些汇编的基本指令:
- NOP: no operation,浪费一个时钟周期什么都不做
- LDS : load stack pointer with a value,给SP指针赋值
- PSHx: push the contains of register ‘x’ into stack,把内部的x寄存器的值入栈
- PULLx: pull from the stack and put in register ‘x’,从堆栈弹出一个数到寄存器x
- JSR : jump to subroutine,跳转到一个子函数
- RTS : return from subroutine,从子函数返回
下面我们将分析一段代码在16bitCPU的执行过程中堆栈的变化
0x3005: NOP
0x3006: LDS $2000
0x3008: PSHA
0x3009: PSHB
0x300A: JSR SubFunc
0x300C: PULLA
0x300D: PULLB
………