转载自点击打开链接
ARM体系架构中,是不允许cpu直接访问内存单元。
为了解决访问内存单元的需要,使用寄存器作为中继,内存和寄存器通过load/store指令交互,cpu在访问寄存器。
内存单元 和 寄存器 直接的数据交互。
- 单寄存器指令 ldr str
- 多寄存器指令 ldm stm
- 交互指令 swp
ldr 内存单元 ----> 寄存器 (
l是left)红字的部分只适用于单寄存器指令,多寄存器指令正好相反
str 寄存器 ----> 内存单元(
t是to)
LDR{<cond>}{<size>} Rd, <address>
STR{<cond>}{<size>} Rd, <address>
{} :可选
{<cond>} :条件码
{<size>} :传送单元大小
Rd :寄存器
<address> :内存地址
1 ---
标号寻址 (地址的助记符)
str r1,val @ *(val) = r1
val:
.word 0x11223344
2---
寄存器间接寻址
mov r0,#0x41000000
str r1,[r0] @ *(r0) = r1
3---
基址变址寻址
mov r0,#0x41000000
str r1,[r0,#4] @ *(r0
+4) = r1
1--- 立即数
str r1,[r0,#4]
2--- 寄存器
mov r2,#4
str r1,[r0,r2]
3--- 寄存器移位
mov r2,#1
str r1,[r0,r2,lsl #2]
1-- 前索引
str r1,[r0,#4] @ *(r0+4) = r1 类似 *(p+1)
2-- 自动索引
str r1,[r0,#4]! @ r0 =r0+4 *(r0)=r1 类似
*(++p) p=p+1、*p
3-- 后索引
str r1,[r0],#4 @ *(r0)=r1 r0 =r0+4 类似
*p++ *p、p=p+1
第一组:
ldr r0,=0xff @ r0=0xff
mov r1,#0xff @ r0=*(0xff)
ldr r0,[r1]
第二组:
ldr r0, =val @ r0 =val地址
ldr r0,val @ r0 =*(val的地址)
val
.word 0x41000000
指定指令访问内存单元中的
几个字节 4个、2个、1个
4个 :默认
2个 :H
1个 :B
低位优先使用,高位补0
ldm 内存块 ---给-> 多个寄存器
stm 多个寄存器 ---
给-> 内存块
<LDM>{<cond>}<addressing_mode> Rb{!}, <寄存器 list>
<STM>{<cond>}<addressing_mode> Rb{!}, <寄存器 list>
{<cond>} :条件码(可选)
<addressing_mode> :地址模式
Rb : 内存块的首地址
{!} :是否更新基址
<寄存器 list> :寄存器列表
I --- 加
D --- 减
A --- 后 :地址后操作
B --- 先 :地址先操作
IA ---
先操作数据,再操作地址(
加)
IB --- 先操作地址(加),再操作数据
DA --- 先操作数据,再操作地址(减)
DB --- 先操作地址(减),再操作数据
寄存器列表写法:
1-- 罗列
{r1,r2,r3,r4,r7}
2-- 连续的寄存器可以缩写
{r1-r4,r7}
例子:
mov r4,#0x41000000
stmia r4!,{r0-r3}
注意:
存储顺序与寄存器列表的顺序无关,永远都是小号寄存器对应小地址。
大括号中无论怎么排列,都是r0放在0x41000000地址上
(1) ldm -- 出栈 --- pop
stm -- 压栈 --- push
(2)
栈操作的地址模式
F 满 --- sp指向的空间,有数据
E 空 --- sp指向的空间,无数据
D 减 --- 栈向地址减小的方向增长
A 增 --- 栈向地址增大的方向增长
(3)
ARM体系结构下,栈都是满减的栈
满减栈(fd)
stmfd -- 压栈 --- (--i) --相当于地址先减1,再在地址上放数据
这里说明在压栈的时候地址指针sp指向了栈顶的上一个元素
ldmfd -- 出栈 --- (i++) --相当于先将地址上的数据取走,地址再加