目录
8.1多寄存器内存访问指令
@多寄存器内存访问指令
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
MOV R11,#0x4000020
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}
8.2多寄存器内存访问指令的寻址方式
@多寄存器内存访问指令的寻址方式
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
MOV R11,#0x4000020
STMIA R11!,{R1-R4} @STM的默认后缀为IA
STMIB R11!,{R1-R4}
STMDA R11!,{R1-R4}
STMDB R11!,{R1-R4}
R11在原有基础上增加16,存入了16个字节。
STMIA与STMIB
相同点:地址越来越大
不同点:A从指定地址存,B从指定地址存先加4再存。A先存数据后增长地址,B先增长地址后存数据。
STMDA与STMDBA
相同点:从高地址往低地址存
不同点:A从指定地址存,B从指定地址存先减4再存。A先存数据后减少地址,B先减少地址后存数据。
8.3栈的种类与使用
栈的概念
栈的本质就是一段内存,程序运行时用于保存一些临时数据。如局部变量、函数的参数、返回值、以及程序跳转时需要保护的寄存器等。
栈的分类
增栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
减栈:压栈时栈指针越来越大,出栈时栈指针越来越小。
满栈:栈指针指向最后一次压入到栈中的数据,压栈时需要先移动栈指针到相邻位置然后再压栈
空栈:栈指针指向最后一次压入到栈中的数据的相邻位置,压栈时可直接压栈,之后需要将栈指针移动到相邻位置。
栈分为空增(EA)、空减(ED)、满增(FA)、满减(FD)四种
ARM处理器一般使用满减栈---STMDB
@栈的种类与使用
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
MOV R11,#0x4000020
STMDB R11!,{R1-R4}
LDMIA R11!,{R6-R9}
8.4栈的应用举例
@ 栈的应用举例
@ 1.叶子函数的调用过程举例
@ 初始化栈指针
@ MOV SP, #0x40000020
@ MIAN:
@ 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
@ 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}
@ MOV R1, #10
@ MOV R2, #20
@ BL FUNC2
@ SUB R3, R2, R1
@ LDMFD SP!, {R1,R2,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压栈保护
作业
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
答:
BL FUNC
STMFD SP!, {R1,R2}
LDMFD SP!, {R1,R2}