- 当程序运行最后一条指令时,PC会接着自增,会出问题
@ 多寄存器内存访问指令
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:多寄存器使用花括号
当寄存器编号不连续时,使用逗号分隔
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV R4, #4
MOV R11,#0x40000020
@ 当寄存器编号不连续时,使用逗号分隔
STM R11,{R1,R2,R4}
@ 不管寄存器列表中的顺序如何,存取时永远是低地址对应小编号的寄存器
STM R11,{R3,R1,R4,R2}
@ 自动索引照样适用于多寄存器内存访问指令
STM R11!,{R1-R4}
- R1-R4一共有16个字节,那么自动索引后,R11也会自加16
@ 多寄存器内存访问指令的寻址方式
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处理器一般使用满减栈
@ 栈的种类与使用
MOV R1, #1
MOV R2, #2
MOV R3, #3
MOV R4, #4
MOV R11,#0x40000020
STMDB R11!,{R1-R4}
LDMIA R11!,{R6-R9}
注意:!!!
- 为了避免写程序容易出错,在arm指令集里面将空增(EA)、空减(ED)、满增(FA)、**满减(FD)**设置了单独的后缀
@ 栈的种类与使用 MOV R1, #1 MOV R2, #2 MOV R3, #3 MOV R4, #4 MOV R11,#0x40000020 STMFD R11!,{R1-R4} LDMFD R11!,{R6-R9}
结果相同
- FD这些不是新指令,通过反编译可以看到会被替换
.text @表示当前段为代码段
.global _start @声明_start为全局符号
_start: @汇编程序的入口
MAIN:
MOV R1, #3
MOV R2, #5
BL FUNC
ADD R3, R1,R2
B STOP
FUNC:
MOV R1, #10
MOV R2, #20
SUB R3, R2, R1
MOV PC, LR
STOP:
B STOP @死循环,防止程序跑飞
.end @汇编程序的结束
从结果来看可以看出子函数和主函数寄存器使用一样的寄存器,主函数所使用的寄存器值被覆盖掉了
为了避免这种情况就可以使用栈来暂时储存主函数的值
.text @表示当前段为代码段
.global _start @声明_start为全局符号
_start: @汇编程序的入口
@ 初始化栈指针
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}@将破坏的R1,R2再重新赋值
MOV PC, LR
STOP:
B STOP @死循环,防止程序跑飞
.end @汇编程序的结束
@ 2.非叶子函数的调用过程举例
MOV SP, #0x40000020
MIAN:
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
MOV PC, LR
FUNC2:
STMFD SP!, {R1,R2}
MOV R1, #7
MOV R2, #8
LDMFD SP!, {R1,R2}
MOV PC, LR
@ 执行叶子函数时不需要对LR压栈保护,执行非叶子函数时需要对LR压栈保护
1.以下代码为使用汇编语言模拟C语言叶子函数的调用过程,按照如下要求补全代码
注:
使用满减栈
MOV SP, #0x40000020
MIAN:
MOV R1, #3
MOV R2, #5
@调用FUNC子程序
1______________
ADD R3, R1, R2
B STOP
FUNC:
@压栈保护现场
2______________
MOV R1, #10
MOV R2, #20
SUB R3, R2, R1
@出栈恢复现场
3______________
MOV PC, LR
STOP:
B STOP
1. BL FUNC
2. STMFD SP!, {R1,R2}
3. LDMFD SP!, {R1,R2}