FreeRTOS学习笔记-------基础知识

本文详细介绍了ARM汇编中的存储器访问指令LDR和STR,以及压栈(PUSH)和出栈(POP)操作。文章还探讨了栈在任务切换、函数调用和中断处理中的作用,以及算数运算指令如加法的使用示例。

常见汇编指令

存储器访问指令

ARM不能直接访问存储器,比如RAM中的数据,一般借助存储器访问指令,通过内核寄存器Rx(x=0~12)完成存储器的读写。常用的存储器访问指令有两种:LDR和STR,用法如下表所示:

指令描述
LDR Rd,[Rn, #offset]从存储器Rn+offset的位置读取数据放到Rd中
STR Rd,[Rn, #offset]将Rd中的数据写入到存储器中的Rn+offset位置

1、LDR指令

LDR主要用于从存储加载数据到寄存器 Rx中, LDR也可以将一个立即数加载到寄存器 Rx中, LDR加载立即数的时候要使用“ “=”,而不是 “#”。在嵌入式开发中 LDR最常用的就是读取 CPU的寄存器值,示例代码如下:

LDR R0, =0x0209C004
LDR R1, [R0, #0x00]

2、STR指令

LDR是从存储器读取数据, STR就是将数据写入到存储器中,示例代码如下:

STR R2, [R0, 0x00]

LDR和 STR都是按照字进行读取和写入的,也就是操作的 32位数据,如果要按照字节、
半字进行操作的话可以在指令“ LDR”后面加上 B或 H,比如按字节操作的指令就是 LDRB和
STRB,按半字操作的指令就是 LDRH和 STRH。

压栈和出栈指令

我们通常会在A函数中调用B函数,当B函数执行完以后再回到A函数继续执行。要想再跳回A函数以后代码能够接着正常运行,那就必须在跳到B函数之前将当前处理器状态保存起来 (就是保存 R0~R15这些寄存器值 ),当B函数执行完成以后再用前面保存的寄存器值恢复R0~R15即可。保存 R0~R15寄存器的操作就叫做现场保护,恢复 R0~R15寄存器的操作就叫做恢复现场。在进行现场保护的时候需要进行压栈 (入栈 )操作,恢复现场就要进行出栈操作。压栈的指令为 PUSH,出栈的指令为 POP。PUSH和 POP是一种多存储和多加载指令,即可以一次操作多个寄存器数据,他们利用当前的栈指针SP来生成地址, PUSH和 POP的用法如下表所示:

指令描述
PUSH <reg list>将寄存器列表存入栈中
POP <reg list>从栈中恢复寄存器列表

注意:PUSH {R0, R1}和PUSH{R1, R0}效果是一样的,因为按照ARM规范是按照寄存器序列号顺序开始入栈,且从小序列号开始入栈。

算数运算指令

在嵌入式开发中最常会用的就是加减指令,乘除基本用不到。

加法指令如下表所示:

指令计算公式备注
ADD Rd, Rn, RmRd = Rn + Rm加法指令
ADD Rd, Rn, #immedRd = Rn + #immed
ADC Rd, Rn, RmRd = Rn + Rm + 进位带进位的加法指令
ADC Rd, Rn, #immedRd = Rn + #immed + 进位

 示例代码

在单片机中,代码存储在Flash中,数据存储在RAM中。下列代码对应的反汇编如下图所示,指令从Flash中取出,然后对RAM中的数据执行对应的操作。函数传递参数时,第一个参数传递给R0,第二个传递给R1。

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

栈的作用

什么是现场?即发生中断或者函数切换时,内核寄存器的值。现场保护即将内核寄存器的值存入栈中,现场恢复即从栈中恢复内核寄存器的值。

栈的作用主要如下:

  • 任务切换、函数调用或者中断发生时,现场的保护与恢复;
  • 局部变量的存储,下图为局部变量的实例。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值