ARM体系结构——ARM指令2——多寄存器内存访问与栈
ARM体系结构与接口技术——ARM指令2——多寄存器内存访问与栈
栈
- 栈的概念:
- 栈的本质就是一段内存,程序运行时用于保存一些临时数据。
- 如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等。
- 栈的分类
- 增栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
- 减栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
- 满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻位置然后再压栈。
- 空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后需要将栈指针移动到相邻位置。
- 栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种。
- ARM处理器一般使用满减栈。
ARM多寄存器内存访问
@ 多寄存器内存访问 .text .global _start _start: 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指令+后缀可以完成不同的寻址方式 @ I和D代表寄存器保存的地址自动增长和字段降低 @ A和B代表寄存器 存储内存之后变化 和 存储内存之前变化 @STMIA R11!,{R1-R4} @ 先存储再增长地址 @STMIB R11!,{R1-R4} @ 先增长地址再存储 @STMDA R11!,{R1-R4} @ 先存储再降低地址 @STMDB R11!,{R1-R4} @ 先降低地址再存储 STOP: B STOP .end
基于起始地址为0x40000020,存储4个字节,4种寻址方式:
寄存器的内存访问实现栈
@ 寄存器的内存写入和读取操作就是栈的实现
.text .global _start _start: @MOV R1,#1 @MOV R2,#2 @MOV R3,#3 @MOV R4,#4 @MOV R11,#0x40000020
@ 前面提到ARM一般使用的是满减栈,与之对应的寄存器访问寻址方式就是SMTDB和LDMIA @STMDB R11!,{R1-R4} @ 先降低寄存器地址,再存储到内存 @LDMIA R11!,{R6-R9} @ 先存储数据到寄存器,再增长地址
@ 编译器可以实现替换的功能,直接使用满减栈后缀FD STMFD R11!,{R1-R4} @ 满减栈压栈,编译之后会换成STMDB LDMFD R11!,{R6-R9} @ 满减栈出栈,编译之后会换成LDMIA STOP: B STOP .end
栈的应用——C语言函数调用
@ 栈的应用:函数调用 .text .global _start _start: MOV SP,#0x40000020 @ 初始化栈指针 MAIN: MOV R1,#3 MOV R2,#5 BL FUNC1 ADD R3,R1,R2 B STOP FUNC1: STMFD SP!,{R1,R2,LR} @ 压栈保护现场 MOV R1,#10 MOV R2,#20 SUB R3,R2,R1 BL FUNC2 LDMFD SP!,{R1,R2,LR} @ 出栈恢复现场 MOV PC,LR FUNC2: STMFD SP!,{R1,R2,LR} @ 压栈保护现场 MOV R1,#10 MOV R2,#20 ADD R3,R2,R1 LDMFD SP!,{R1,R2,LR} @ 出栈恢复现场 MOV PC,LR STOP: B STOP .end
END