任务和内存的栈

发布时间:2023年12月29日

任务是什么?

任务是可以运行着的函数,本身并不是函数,因为任务是可以创建、删除、切换等操作的。

void add_val(int *pa, int *pb)
{
   volatile int tmp;
   tmp = *pa;
   *pa = tmp + *pb;
}

void TaskFunction(void *param)
{
   int a = 1;
   int b = 2;
   
   add_val(&a, &b);
}

看一个函数中执行A+B 的全过程:
在这里插入图片描述
运行过程:
① CPU从内存把变量a的值读入CPU的R0寄存器;

② CPU从内存把变量b的值读入CPU的R1寄存器;

③ CPU计算a和b这两个变量的值的和,然后放入CPU的R0寄存器;

④ CPU将R0寄存器的值写到内存上变量a的位置;

在这个过程中,CPU是怎么知道要做① ② ③ ④这几件事情的?那肯定是程序员编写的程序来控制的。程序员将编写好的程序保存到Flash中,CPU从Flash中的取出指令,根据指令忠诚的执行它。

指令是什么?

load  ; 加载
store ; 存储
add   ; 相加

指令的三要素:源;目的;长度。
长度:变量的长度,比如int a;这个变量的长度是4bytes(32bits的处理器);

在这里插入图片描述

如果上诉程序在执行的过程之中被打断,那么就需要保存现场与恢复现场。
保存的是什么?是CPU将打断前的程序运行到的地址(下一条志汇编指令的地址)、寄存器的值保存到栈中,当执行完打断后,又从栈中读取出来恢复现场继续执行。

另外,如果有外界又打断了运行的函数,那么栈的内容需要保存吗?
解答:不需要,栈的内容无法按保存,只需要栈的位置。下一次回来的时候,CPU继续找到的之前保存的寄存器和局部变量。
在这里插入图片描述
主要LR保存的函数执行完的下一个指令的地址。
为了反之寄存器地址的覆盖,在调用函数的内部已经尽心了寄存器返回地址的保存,以防覆盖。

函数调用与内存中栈的实现

在这里插入图片描述
一个函数执行完,会去栈中取出LR的值,去执行返回地址处的程序。
在这里插入图片描述

文章来源:https://blog.csdn.net/qqmrchen124/article/details/135277648
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。