1. 内存操作指令
一次读写 4个字节
ldr : 读内存 数据到 寄存器中
str : 写内存 将寄存器中的 数据 写入到内存
ldrb / strb 一次读写 1个字节
ldrh / strh 一次读写 2个字节
2. 定义类型和访问
2.1 定义
.data @ 数据段
@整型 int a =5
a: .word 5@字符型 char c = 'a'
c: .Byte 'a'.Byte 0 @ 空一个内存位置 以满足下一个内存地址是2字节对齐的@短整型 short x = 7
x: .short 7@ 数组int arr[5] = {1,2,3,4,5}
arr: .word 1,2,3,4,5
2.2 访问和写入
2.2.1 整型的读写
@访问整型
ldr r0,=a @将a的地址存放到r0
ldr r1,[r0] @r1 = *r0
@写入
mov r2,#8
str r2,[r0] @*r0 = r2nop
2.2.2 char和short的读写
@char和short的读写
ldr r0,=c
ldrb r1,[r0] @ 读一个字节
ldr r0,=x
ldrh r1,[r0] @ 读两个字节
3 访问数组
3.1 前索引
*(p+1) 前索引
就是这样的造型 ldr r2,[r0, #4] @ arr[1] *(arr+1)
@前索引
ldr r0,=arr
ldr r1,[r0, #0] @ r1 = arr[0] *(p+1) 这里和下面的0 4 8 是因为整型4字节对齐
ldr r2,[r0, #4] @ r2 = arr[1]
ldr r3,[r0, #8] @ r2 = arr[2]
@ ....
3.2 后索引
*p++
@ 后索引
ldr r1,[r0],#4 @ 先把r0取出来,然后自增4字节 相当于 *p++;
ldr r2,[r0],#4
ldr r3,[r0],#4
@ ....
3.3 自动索引
*++p
@自动索引
ldr r1,[r0,#4]! @ *++p; 先p++,然后再*P
4. 多寄存器操作指令:
4.1 ldm和stm
ldm : 连续从内存中 读取多个整型数据到 指定的多个寄存器中
@多寄存器操作指令
ldr r0,=arr
ldm r0,{r1-r5} @ 将r0地址后的 5个整型数据 取出依次放到R1-R5中
@ldm r0,{r1,r3-r5,r7} @ 将r0地址后的 5个整型数据 放入r1,r3-r5,r7中
stm : 将多个寄存器中的 数据 写入到 连续的内存中
@多寄存器操作指令
ldr r0,=arr
stm r0,{r6-r10} @ 将r6-r10中的值 全部依次写入r0对应的地址中
4.2 栈操作:
满栈: 栈指针指向的位置 有数据
空栈: 栈指针指向的位置 无数据
增栈: 存入数据时 栈指针在向大地址方向移动
减栈: 存入数据时 栈指针在向小地址方向移动
满增栈: 入栈 *++p 出栈 *p--;
满减栈: 入栈 *--p 出栈 *p++;
空增栈: 入栈 *p++ 出栈 *--p;
空减栈: 入栈 *p-- 出栈 *++p;
C标准指定: 栈使用 满减栈 fd后缀
ldmfd 满减栈 出栈
stmfd 满减栈 入栈
4.2.1 栈的操作流程
定义栈空间
@ 定义栈空间
stack_start:.space 1024 @给栈控件1024字节大小的空间
stack_end:
操作栈
@栈操作方式
@sp栈指针
@ 栈初始化 本质就是给sp赋值为一段内存空间
ldr sp,=stack_end @ 因为采用满减栈, 因此栈底在大地址方向
stmfd sp!,{r0-r12} @ 将r0-r12寄存器入栈保存 且栈指针要移动
ldmfd sp!,{r0-r12} @ 从栈中 恢复 r0-r12的值
5. 函数
了解即可
func: @ r0-r3 入参@ 将r4-r12 入栈保存stmfd sp!,{r4-r12,lr}mov r12,sp @ 保存 原始栈顶@ 定义了局部变量 int a =5;mov r0,#5 stmfd sp!,{r0} @ 局部变量入栈@ ....ldr r10,[sp] @ 访问局部变量a@ 函数返回 mov sp, r12@ 恢复 r4-r12 弹栈 return ldmfd sp!,{r4-r12,pc}NOP
6. 内存交换指令
实现 同步互斥 保证原子操作的一种手段
swp r2,r1,[r0] 将r0地址中的数据取出到R2中,同时将r1中数据放入到R0地址中
了解即可
6.1 互斥锁: 逻辑
假设r0 互斥锁标记 0 没上锁 1 上锁了
这种操作先读然后再写,这个两个步骤了,操作有可能再中间被打断,不能保证操作的原子性
if( R0 )阻塞等待else R0 = 1; @ 操作可能会被打断
这种的使用swp 时读取和写入是一条指令,cpu打断一条指令的最小单位是,一条指令,所以,swp不可能别打断,保证了操作的原子性
R1 = 1;swp r2,R1,[r0] @ 对R0地址的 读写操作是原子性的 if (r2) 阻塞等待else 处理互斥内容
7. 特权指令: 该指令只能在 特权模式下可以执行
CPSR,SPSR进行读写操作
mrs/msr
@特权指令 msr/mrs
mrs r0,cpsr @ 将cpsr中的值 取出 存放到 R0中
MOV R0,#0XD0 @1101 0000
msr cpsr,R0 @ 将r0中的值 写入到cpsr寄存器中
MOV R0,#0XD3
msr cpsr,R0 @ USR模式中 没有特权 无法修改cpsr