ARM体系结构及接口技术介绍(三)内存访问指令

(一)Load/Store内存访问指令

是一类可以在ARM寄存器和存储器之间进行数据传递的指令

1. 单寄存器读写操作

指令码

ldr:把存储器中的一个字(四个字节)装入一个寄存器中
str:把寄存器中的一个字(四个字节)存储到存储器中
ldrh:把存储器中的一个半字(两个字节)装入寄存器中
strh:把寄存器中的一个半字(两个字节)存储到存储器中
ldrb:把存储器中的一个字节装入一个寄存器中
strb:把寄存器中的一个字节存储到存储其中

ld:Load
st:Store
r:Register
h:Half
b:Byte

指令格式

ldr/ldrh/ldrb Rd, [Rm]
[Rm]寄存器中额数据将被当作一个地址看待
将[Rm]指向的地址空间的数据存储到Rd寄存器中

str/strh/strb Rn, [Rm]
将Rd寄存器中的数据加载到[Rm]指向的地址空间

使用示例

查看内存中的值

地址的使用

.globl _start 

_start:
	@将r1存储的数据放到r0指向的地址空间中
	ldr r0,=0x40000800  @地址
	ldr r1,=0x12345678  @数据
	str r1,[r0]
	
	@@@拆分数据
	@按字节读取,分别存储在r2,r3,r4,r5寄存器中
	ldrb r2,[r0,#0]!
	ldrb r3,[r0,#1]!
	ldrb r4,[r0,#1]!
	ldrb r5,[r0,#1]!
	
	@@@拼接数据
	@将各字节左移相应位数,然后用orr拼接
.if 0
	lsl r3,r3,#8
	lsl r4,r4,#16
	lsl r5,r5,#24
	
	orr r6,r6,r2
	orr r6,r6,r3
	orr r6,r6,r4
	orr r6,r6,r5
.else
	orr r6,r6,r2,lsl #0
	orr r6,r6,r3,lsl #8
	orr r6,r6,r4,lsl #16
	orr r6,r6,r5,lsl #24
.endif	
	
	stop:	
	b stop	
.end		
地址偏移

str Rn, [Rm, #offset]
将Rn寄存器中的数据写到[Rm+offset]指向的地址空间中,Rm寄存器中的地址不变

str Rn,[Rm],#offset
将Rn寄存器中的数据写到[Rm]指向的地址空间中,然后更新Rm寄存器中的地址

str Rn,[Rm,#offset]!
将Rn寄存器中的数据写到[Rm+offset]指向的地址空间中,同时更新Rm寄存器中的地址
!:作用是更新Rm寄存器中的地址

  • 注:
  • ldr/str 偏移地址必须是4的整数倍,可以是负数
  • ldrh/strh 偏移地址必须是2的整数倍,可以是负数
  • ldrb/strb 偏移地址必须是1的整数倍,可以是负数

2. 栈空间读写操作

栈的分类

增栈:压栈后,

减栈:压栈后,

空栈:当前栈指针指向的栈空间中,没有有效数据,
因此可以先向栈空间中压入新的数据,然后再移动栈指针,指向一个没有有效数据的空间

满栈:当前栈指针指向的栈空间中有有效数据,
需要先移动栈指针指向一个没有有效数据的空间,然后再压栈

栈空间操作方式

满增栈:Full Ascending Stack
stmfa/ldmfa

满减栈:Full Descending Stack
stmfd/ldmfd
空增栈:Empty Ascending Stack
stmea/ldmea
空减栈:Empty Descending Stack
stmed/ldmed

m:multi

满减栈操作指令

ARM处理器默认使用满减栈

ldmfd sp!,{寄存器列表}
	sp:栈指针寄存器,存储的是指向的栈空间的地址
	!:出栈之后,更新栈指针,栈指针向高地址方向移动

stmfd sp!,{寄存器列表}

寄存器列表的格式要求:
1> 如果寄存器的编号是连续的使用"-“隔开,
2> 如果寄存器的编号不连续使用”,"隔开,
3> 寄存器列表中的寄存器要求从小到大的编号进行书写
4> 不管寄存器列表的寄存器顺序如何书写,永远都是低地址对应小编号的寄存器,高地址对应大编号的寄存器

使用示例

函数多级跳转,保存现场时需要将LR的值也进行保存,否则第二次跳转的LR会覆盖掉第一次跳转时保存的LR值

.globl _start 

_start:
	ldr sp, =0x40000820  @ 初始化栈指针
	
	mov r0, #0x100
	mov r1, #0x200
	bl add_func
	add r2, r0, r1     @ r2 = r0 + r1 = 0x300
	
	b stop
	
	add_func:
		stmfd sp!, {r0-r1,lr}	@ 压栈保存现场
		mov r0, #0x300
		mov r1, #0x400
		bl add_func2
		add r3, r0, r1   @ r3 = r0 + r1 = 0x700
		ldmfd sp!, {r0-r1,lr}  @ 出栈恢复现场
		mov pc, lr
	
	add_func2:
		stmfd sp!, {r0-r1}	@ 压栈保存现场
		mov r0, #0x500
		mov r1, #0x600
		add r4, r0, r1   @ r4 = r0 + r1 = 0xB00
		ldmfd sp!, {r0-r1}  @ 出栈恢复现场
		mov pc, lr
	
	stop:	
	b stop	
.end		
	

(二)特殊功能寄存器读写指令

对CPSR寄存器进行读写操作的指令

msr:将普通寄存器中的数据写到特殊功能寄存器(CPSR)中
mrs:将特殊功能寄存器(CPSR)中的数据写到普通寄存器中
m:move s:special r:register

msr cpsr,Rn
mrs Rd,cpsr

系统一上电就在SVC模式,切换处理器工作模式,使其处于User模式下
在修改CPSR寄存器的M位时,需保证其他位不变
在这里插入图片描述

.globl _start 

_start:
.if 1
	@方法一:直接使用msr指令,给CPSR寄存器赋值
	msr cpsr,#0xD0
.else
	@方法二:
	mrs r0,cpsr
	bic r0,r0,#0x1f @先清零
	orr r0,r0,#0x10
	msr cpsr,r0
.endif
	stop:	
	b stop	
.end		

(三)软中断指令

指令码:swi

sw:software
i:interrupt

指令格式

swi{cond} 软中断号

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值