[FreeRTOS 基础知识] 栈 与 汇编语言


栈的概念

所谓的栈就是一块空间的内存,CPU的SP寄存器指向它,它可以用于函数调用,局部变量,多任务系统里保存现场。


使用C语言实现 栈

volatile int num=0;

int fun_b(volatile int a)
{
    a = a+2;
    return a;
}    

int fun_c(volatile int a)
{
    a = a+2;
    return a;
}    

void fun_a(volatile int a)
{
    num = fun_b(a);
    num = fun_c(num);
}

int main(void)
{
    fun_a(99);
    
    return 0;
}

代码中函数调用关系:
main -> fun_a
fun_a -> fun_b
-> fun_c


通过代码反汇编解析 栈

编译代码时,制作反汇编步骤: 在配置中添加命令

fromelf --text  -a -c --output=xxx.dis xxx.axf

在这里插入图片描述

其中的xxx.axf文件在linker中获取

在这里插入图片描述

运行后反汇编文件在工程目录下。查看反汇编代码:
在这里插入图片描述
main函数中使用BL命令跳转到fun_a函数(pc=0x80002d0,lr=0x08000308)
在这里插入图片描述
fun_a函数中使用BL命令跳转到fun_b函数(pc=0x80002ec,lr=0x080002d8),运行完fun_b函数后,使用BL命令跳转到fun_c函数(pc=0x80002f6,lr=0x080002e2)
在这里插入图片描述
在上面的过程中发现lr的值会被覆盖,若被覆盖就会导致找不到之前函数返回的地方。因此在每个函数的第一条反汇编会把lr值保存到栈中(使用push命令),当函数结束的时候使用pop命令回到之前的位置。

整个栈过程如下图所示:
在这里插入图片描述


RAM架构

为了更好的理解栈的作用,可以结合RAM架构以及汇编语言。
在这里插入图片描述
SOC芯片上有很多模块:CPU(主要运算数据)、RAM(内存,数据存储)、Flash(指令存储)等其他模块。

计算a+b,需要经过四个步骤:
1、从RAM中取出a值;
2、从RAM中取出b值;
3、在CPU 运算单元模块 运算;
4、将运算结果存到RAM中的a位置
在这里插入图片描述
CPU中有15个寄存器(R0—R15),其中普通寄存器R0~R12是存储数据
特殊寄存器R13别名为SP:栈;
特殊寄存器R14别名为LR:返回地址;
特殊寄存器R15别名为PC:当前指令地址;

CPU 从RAM中取出来的ab数值 会存入R0~R12中的任意寄存器中。
CPU要执行a+b的功能,就需要从Flash中获取指令。如下图所示,
在这里插入图片描述
1、程序员将编写好的程序编译成执行文件,使用特有的烧写工具将执行文件烧写到Flash中,因此在Flash保存就是机器语言。
2、CPU根据R15(当前指令地址)从Flash中读取指令到CPU,执行指令(a+b)
3、CPU根据汇编中的地址取出运算中要使用的ab值,保存在CPU的寄存器中
4、CPU从寄存器中取出值进行运算,并将计算结果保存到RAM中(a地址)


汇编语言

根据上述的反汇编内容,理解下指令a+b的过程。使用上面的fun_c函数为例。
在这里插入图片描述
读指令 LDR (Load 加载) :LDR r0, [ addr A ]
描述:将A地址读到R0寄存器(4字节)
LDRH(2字节)
LDRB(1字节)

写指令 STR (Store 存储):STR r0, [ addr A ]
描述:将R0地址写到A地址中(4字节)

运算符 ADDS:ADDS r0,r1,r2
描述:r1+r2,相加的值存入r0寄存器中

入栈 PUSH:PUSH { r0, LR }
描述:将r0,LR的值压入栈中,本质就是向RAM写两次数据。其中存入RAM的地址就是特殊寄存器R13 sp值
在这里插入图片描述
假设sp的地址为0x100,则压栈的时候 根据 “高标号的寄存器,存在高地址中”
(注: { } 中的顺序无关)
SP=SP-4;LR存入SP所指向的地址;SP=SP-4;R0存入SP所指向的地址(SP-4);SP=SP-4

出栈 POP:POP { r3, PC }
描述:从栈中取出值赋给r3,PC,本质就是向RAM读两次数据。其中从SP当前所指向的地址开始读数据。
从SP所指的栈地址取出数据赋给 r3;SP= SP+4;从当前SP所指的栈地址取出数据赋给PC;SP= SP+4

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bazinga bingo

您的鼓励就是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值