ARM汇编:多寄存器内存访问指令
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV R4, #4
MOV R11,#0x40000020
STM R11,{R1-R4} @ 将R1-R4寄存器中的数据写入到以R11为起始地址的内存空间中
LDM R11,{R6-R9} @ 将以R11为起始地址的内存空间中的数据读取到R6-R9寄存器中
当寄存器编号不连续时,使用逗号分隔
STM R11,{R1,R2,R4}
不管寄存器列表中的顺序如何,存取时永远是低地址对应小编号的寄存器
STM R11,{R3,R1,R4,R2}
自动索引照样适用于多寄存器内存访问指令
STM R11!,{R1-R4}
多寄存器内存访问指令的寻址方式
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV R4, #4
MOV R11,#0x40000020
STMIA R11!,{R1-R4} @ 先存储数据,后增长地址
STMIB R11!,{R1-R4} @ 先增长地址,后存储数据
STMDA R11!,{R1-R4} @ 先存储数据,后递减地址
STMDB R11!,{R1-R4} @ 先递减地址,后存储数据
栈的种类与使用
栈的概念
栈的本质就是一段内存,程序运行时用于保存一些临时数据
如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等
栈的分类
栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种
ARM处理器一般使用满减栈
多寄存器内存访问指令的寻址方式(上一节)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rqysL3rd-1669449419159)(…/00images/多寄存器内存访问指令的寻址方式.png)]
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV R4, #4
MOV R11,#0x40000020
STMFD R11!,{R1-R4} @ 满减栈,不需要考虑四种寻址方式了,理应STMDB
LDMFD R11!,{R6-R9} @ 满减栈,不需要考虑四种寻址方式了,理应LDMIA
栈的应用举例
- 叶子函数的调用过程举例(不调用其他函数)
MOV SP, #0x40000020 @ 初始化栈指针
MAIN:
MOV R1, #3
MOV R2, #5
BL FUNC
ADD R3, R1, R2
B STOP
FUNC:
STMFD SP!, {R1,R2} @ 压栈保护现场
MOV R1, #10
MOV R2, #20
SUB R3, R2, R1
LDMFD SP!, {R1,R2} @ 出栈恢复现场
MOV PC, LR
- 非叶子函数的调用过程举例(会调用其他函数)
MOV SP, #0x40000020 @ 初始化栈指针
MAIN:
MOV R1, #3
MOV R2, #5
BL FUNC1
ADD R3, R1, R2 @ 加法运算
B STOP
FUNC1:
STMFD SP!, {R1,R2,LR} @ 压栈保护现场(LR)
MOV R1, #10
MOV R2, #20
BL FUNC2
SUB R3, R2, R1 @ 减法运算
LDMFD SP!, {R1,R2,LR} @ 出栈恢复现场(LR)
MOV PC, LR
FUNC2:
STMFD SP!, {R1,R2}
MOV R1, #7
MOV R2, #8
MUL R3, R1, R2 @ 乘法运算
LDMFD SP!, {R1,R2}
MOV PC, LR
执行叶子函数时不需要对LR压栈保护,执行非叶子函数时需要对LR压栈保护