- int *p=0X12345678
- *p=100;//向内存中写入数据
- int a= *p;//从内存读取
- 向内存中写:
- str:向内存中写一个字(4字节)的数据
- strh:向内存写半个字(2字节)的数据
- strb:向内存写一个字节的数据
- 从内存读:
- ldr:从内存读取一个字的数据
- ldrh:从内存读取半个字的数据
- ldrb:从内存读取一个字节的数据
- 指令码{条件码} 目标寄存器 [目标地址]
- str 目标寄存器 ,[目标地址]:将目标寄存器的数据写入到以目标地址为起始的内存中
- ldr 目标寄存器 ,[目标地址]:从以目标地址为起始的内存中读一个字的数据到目标寄存器
- mov r1,#0XFFFFFFFF
- ldr r2,=0X40000000
- @向内存写入
- str r1,[r2]
- @从内存读
- ldr r3,[r2]
- 1.前索引
- mov r1,#0XFFFFFFFF
- ldr r2,=0X40000000
- str r1,[r2,#8]@将r1寄存器的值保存到r2+8为起始地址的内存中
- ldr r3,[r2,#8]@从r2+8为起始地址的内存中读
- 2.后索引
- mov r1,#0XFFFFFFFF
- ldr r2,=0X40000000
- str r1,[r2],#8 @将r1寄存器的值保存到r2为起始地址的内存中,r2值=让r2+8
- 3.自动索引
- mov r1,#0XFFFFFFFF
- ldr r2,=0X40000000
- str r1,[r2,#8]! @将r1寄存器的值保存到r2+8为起始地址的内存中,r2=r2+8
- 向内存写:
- stm 目标地址,{寄存器列表}
- 将寄存器列表中每一个寄存器的值都写道目标地址指向的连续空间之中
- 从内存读
- ldm 目标地址,{寄存器列表}
- 将目标地址指向的连续内存中的数据读到寄存器列表中的寄存器中
-
- 注意事项:
- 1.如果寄存器列表中寄存器的编号连续,可以用-表示列表,如果不连续,用,分割寄存器
- {r1-r5,r7}
- 2.无论寄存器列表中如何表示,我们在读写内存的时候始终是低地址 对应低寄存器编号
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000000
- stm r6,{r1,r2,r3,r4,r5} @将r1-r6寄存器的值写道r6指向的连续内存中
- ldm r6,{r7,r8,r9,r10,r11}@从r6指向的连续内存中读取数据保存到r7-r11寄存器中
每次向指定寄存器保存的地址中写入一个数据,保存地址的寄存器保存的地址也会发生相应的改变
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000000
- stm r6!,{r1-r5}
- 先向r6指向的内存中写一个数据,然后r6保存的地址向地址大的方向增长
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000000
- stmia r6!,{r1-r5}
- 先向r6指向的内存中写一个数据,然后r6保存的地址向地址大的方向增长
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000000
- stmib r6!,{r1-r5}
-
- 先让R6寄存器保存的地址往地址大的方向增长,再向R6寄存器保存的地址中写入数据
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000800
- stmda r6!,{r1-r5}
- 先向R6指向的内存中存数据,然后R6寄存器保存的地址往地址小的方向增长
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000800
- stmdb r6!,{r1-r5}
- 先将R6寄存器保存的地址往地址小的方向增长,再往R6寄存器保存的地址内存中存入数据
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- ldr r6,=0X40000000
- stmia r6!,{r1-r5} @ia存,db取
- ldmdb r6!,{r7-r11}
栈指针寄存器:R13/SP
栈:栈本质上就是一段内存,我们在内存中指定一片区域用于保存一些临时数据,这片区域就是栈区
- 增栈:压栈结束后,栈顶往地址大的方向增长
- 减栈:压栈结束后,栈顶往地址小的方向增长
- 空栈:压栈结束后,栈顶区域没有有效数据
- 满栈:压栈结束后,栈顶区域存放有效数据
-
- 空增栈(EA)/空减栈(ED)/满增栈(FA)/满减栈(FD)
- ARM使用的栈是满减栈
- ex1:
- ldr sp,=0X40000020 @指定顶地址
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- push {r1-r5} @压栈
- pop {r6-r10} @将栈顶元素数值出栈
- ex2:
- ldr sp,=0X40000020 @指定顶地址
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- STMDB sp!,{r1-r5} @压栈
- LDMIA sp!,{r6-r10} @将栈顶元素数值出栈
- EX3:
- ldr sp,=0X40000020 @指定顶地址
- mov r1,#1
- mov r2,#2
- mov r3,#3
- mov r4,#4
- mov r5,#5
- STMfd sp!,{r1-r5} @压栈
- LDMfd sp!,{r6-r10} @出栈
- .text
- .global _start
-
-
- _start:
- ldr sp,=0X40000020 @初始化栈
- b main
- main:
- mov r1,#1
- mov r2,#2
- bl func
- add r3,r1,r2
- b main
-
- func:
- @压栈保护现场
- stmfd sp!,{r1,r2}
- mov r1,#3
- mov r2,#4
- sub r4,r2,r1
- @出栈恢复现场
- ldmfd sp!,{r1,r2}
- mov pc,lr @返回main函数
-
-
- wh:
- b wh
-
- .end
- .text
- .global _start
-
-
- _start:
- ldr sp,=0X40000020 @初始化栈
- b main
- main:
- mov r1,#1
- mov r2,#2
- bl func
- add r3,r1,r2
- b main
-
- func:
- @压栈保护现场
- stmfd sp!,{r1,r2,lr}
- mov r1,#3
- mov r2,#4
- bl fun1
- sub r4,r2,r1
- @出栈恢复现场
- ldmfd sp!,{r1,r2,lr}
- mov pc,lr @返回main函数
- fun1:
- @压栈保护现场
- stmfd sp!,{r1,r2}
- mov r1,#4
- mov r2,#5
- mul r5,r1,r2
- @出栈恢复现场
- ldmfd sp!,{r1,r2}
- mov pc,lr
-
-
- wh:
- b wh
-
- .end