内存操作指令

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 = r2

nop

内存操作指令_第1张图片

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]
@ ....

内存操作指令_第2张图片

3.2 后索引

*p++

@ 后索引
ldr r1,[r0],#4     @ 先把r0取出来,然后自增4字节 相当于 *p++;
ldr r2,[r0],#4
ldr r3,[r0],#4
@ ....

内存操作指令_第3张图片

3.3 自动索引

*++p

@自动索引
ldr r1,[r0,#4]!  @ *++p;  先p++,然后再*P

内存操作指令_第4张图片

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中

内存操作指令_第5张图片

stm  :  将多个寄存器中的 数据  写入到 连续的内存中

@多寄存器操作指令
ldr r0,=arr
stm r0,{r6-r10}  @ 将r6-r10中的值 全部依次写入r0对应的地址中

内存操作指令_第6张图片

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 

你可能感兴趣的:(ARM,arm,汇编)