栈的分类以及应用场景

栈的本质就是一段内存,程序运行时用于保存一些临时数据。栈大体可以分为四种类型空增、空减、满增、满减。ARM处理器一般使用满减栈


         目录

1、栈的分类

2、压栈/出栈的两种实现方式

(1) 方式一:使用后缀DB / IA

(2) 方式二:使用后缀FD

3、应用场景


1、栈的分类

从压栈的方向来看,可以分为增栈减栈。所谓增栈指的是入栈时,数据是由低地址往高地址的方向存储的。减栈正好相反。

从指针移动和压栈的顺序来看,可以分为满栈和空栈。所谓满栈,指的是先移动栈顶指针,再存数据,栈顶指针最终指向的内容一定不为空空栈恰恰相反,先存储数据,然后再把栈顶指针移动到下一个位置,此时栈顶指针最终指向的内容一定为空

增/减栈 与 空/满栈两两组合,就得到了栈的四种基本类型:空增(EA)、空减(ED)、满增(FA)、满减(FD)。ARM处理器一般使用满减栈

2、压栈/出栈的两种实现方式

(1) 方式一:使用后缀DB / IA

压栈其实就是将某个寄存器的数据保存到内存中,出栈其实就是从内存中取出数据保存到寄存器。因为ARM处理器是满减栈,入栈的时候,要先让地址自减然后再存数据,这就对应后缀 DB(Decrease Before)

出栈的时候,因为是满减栈,栈顶指针指向的内容一定不为空,此时应该是先取出数据,然后再让地址自增,这就对应后缀 IA(Increase After)

MOV SP!, #0x40000020        @ 初始化栈顶指针
MOV R1, #1
MOV R2, #2
MOV R3, #3
STMDB SP!, {R1-R3}			@ 入栈
LDMIA SP!, {R4-R6}			@ 出栈

 入栈测试:

 出栈测试:

(2) 方式二:使用后缀FD

上面的方法虽然可以达到效果,但是入栈和出栈使用不同的后缀,难免会不大方便,所以栈的四种类型空增(EA)、空减(ED)、满增(FA)、满减(FD)都可以直接作为后缀使用,达到的效果和方式一相同。

MOV SP!, #0x40000020        @ 初始化栈顶指针
MOV R1, #1
MOV R2, #2
MOV R3, #3
STMFD SP!, {R1-R3}			@ 入栈
LDMFD SP!, {R4-R6}			@ 出栈

本质还是会被转换成方式一的指令 

3、应用场景

发生函数调用跳转时,我们需要把寄存器中的数据暂时保存到内存,等函数调用结束,再把数据从内存中取出来。

	MOV SP, #0x40000020			@ 初始化栈顶指针
MAIN:
	MOV R1, #1
	MOV R2, #2
	BL FUNC                    @ 函数跳转
	ADD R3, R1, R2
	B STOP
	
FUNC:
	STMFD SP!, {R1-R2}			@ 保存原本的R1-R2寄存器的值
	MOV R1, #4
	MOV R2, #3
	SUB R4, R1, R2
	LDMFD SP!, {R1-R2}			@ 恢复R1-R2寄存器的值
	MOV PC, LR                  @ 跳转以后不会自动回去,需要自己手动设置PC
STOP:				
	B STOP

发生跳转以后R1-R2的值

回到回到跳转位置的下一个位置时,R1-R2的值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值