找回密码
 注册
关于网站域名变更的通知
查看: 342|回复: 3
打印 上一主题 下一主题

ARM的栈与栈指令

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2021-9-29 13:42 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

EDA365欢迎您登录!

您需要 登录 才可以下载或查看,没有帐号?注册

x
一、定义:栈(Stack)是限定仅在一端进行插入或删除操作的线性表。% T" T9 r' L- k, V% u
因此,对栈来说,可以进行插入或删除操作的一端端称为栈顶(top),相应地,另一端称为栈底(bottom)。不含元素的空表称为空栈。由于堆栈只允许在一端进行操作,因而按照后进先出(LIFO-Last In First Out)的原理运作。从栈顶的定义来看,栈顶的位置是可变的。空栈时,栈顶和栈底重合;满栈时,栈顶离栈底最远。ARM为堆栈提供了硬件支持,它使用一个专门的寄存器(堆栈指针)指向堆栈的栈顶。而且7种模式都有各自独立的堆栈指针,也就是有各自独立的堆栈空间。
* n5 E! P+ L# @* S8 r二、如何描述一个栈$ A7 [$ s4 W/ [" W& G  z: {
准确描述一个栈的特点需要两个参数
" j' X+ N# _6 _8 ?* d$ \! t6 p* Y栈地址的增长方向:ARM将向高地址增长(也叫做向上增长)的栈称为递增栈(ascendant Stack),将向低地址增长(也叫做向下增长)的栈称为递减栈(descendantStack)
. D& K0 P( I4 o4 X7 \5 P栈指针的指向位置:ARM将栈指针指向栈顶元素位置的栈称为满栈(Full Stack),讲栈指针指向即将入栈的元素位置的栈称为空栈(Empty Stack)% N1 D- }+ s9 n6 Y' p% a  ~2 N
根据栈地址增长方向雨栈指针指向位置的不同,自然可以将栈分为四类:
2 M" M5 t" s4 M+ k3 w! H% R% A! e: M/ @) z- m) \0 T: k
下图描述了四种不同类型的栈,其中虚线部分表示即将入栈的元素。  l$ E% n# D) l3 f, L) B
9 F% K7 \/ k' B; Q) K. m
三、栈指令
2 S$ X- G; v. l5 L: r栈的操作指令无非两种:入栈和出栈,由于ARM描述了四种不同类型的栈,因此对应的栈指令一共有8条。
, E' G! \8 Z& H- |/ v; Q
STM:(STore Multiple data)表示存储数据,即入栈。; h8 r: \& N1 w& W# X
LDM:(LoaD Multiple data)表示加载数据,即出栈。
/ F# j" z3 L: b- c9 F. O1 G/ j一般情况下,可以将栈操作指令分解为两步微指令:数据存取和栈指针移动。这两步操作的先后顺序和栈指针的移动方式由栈的类型决定。
8 G; l) h/ }: Q/ O7 N
9 W! @8 z  o2 Z8 O" BARM中存在一组缓冲区操作指令和栈指令是一一对应的,他们完成相同的功能。这些指令含义的区别来源于对存取操作的缓冲区指针地址增长方向,以及存取操作和缓冲区指针移动的先后顺序决定的。这个和前面描述的栈类型的分类原则十分相似。- i: y; M; y5 S' W8 @7 G
, R" z( I5 r" T* x. H; c$ K
四、实例" L  A- X/ o4 B) q" k4 Z
虽然ARM的栈类型和相关的操作指令比较繁琐,但是实际上最常用的还是和x86指令集相同的栈类型:栈向低地址方向增长,且栈指针指向栈顶元素的位置,即ARM的FD栈。因此最常见的ARM栈指令操作是STMFD和LDMFD。
2 f1 |7 m- [5 V* U! G  Q7 \( }例如入栈指令:3 i2 B* Z  V; W
STMFD SP,{R0-R3}& g) _' N8 [5 B
实际的微指令操作为:; J: l5 Q4 H; }, n, W# y* l. u% n
[SP-4]  <=  R3# [* x2 x* S8 Q: T2 r+ v
[SP-8]  <=  R2
% X, k0 J+ {+ e) x. K$ B- o6 W[SP-12] <=  R1
0 t, \) ]1 Z: L3 O  }9 |[SP-16] <=  R08 C4 R; ~9 a! A0 U+ h" @+ h
在ARM的指令系统中,递减栈入栈操作的参数入栈顺序是从右到左依次入栈,而参数的出栈顺序则是从左到右的逆操作。对于递增栈,相应的操作则全部取反。
, {& b- i) u) R, M( K" x例如出栈指令:. E( G0 J$ N; O; h( F/ N2 {' B- H$ M6 s0 D
LDMFD SP,{R4-R7}
# j0 Y2 J' E1 P' b  j实际的微指令操作为:
; m! R# h8 s' C[SP]    =>  R4% S- f/ \# a. n' X: l) X" j" K0 ]
[SP+4]  =>  R59 P% C$ F# S" B/ ^% i
[SP+8]  =>  R6
7 K( B; K" T6 {; _1 Y) V- i[SP+12] =>  R7
( t. E( f) L4 ^. O7 }上述的入栈和出栈指令其实仅仅对栈做了存取操作,并未真正改变SP指针的值。正常情况下,我们希望对栈操作后能自动修改栈指针SP的值,使用如下指令可以达到该目的。; U7 q  q# ?# |# A3 s2 ^
STMFD SP!,{R0-R3}' E" g, w3 I& x* Y) u. K
对应的微指令操作为:
1 s/ p. J% _' s8 q  ][SP-4]  <=  R3/ C) G1 a2 |+ b. V0 i" U0 c) }
[SP-8]  <=  R2
9 E! L# p( R0 p8 g$ b[SP-12] <=  R1: K- ^' p, V" Z8 t
[SP-16] <=  R0/ _6 d* `5 ?+ U1 U$ ~! A
SP      =  SP - 16* z4 k; Q, N: R3 F5 p
同样的:
' q/ u  W8 [/ l) _) \" SLDMFD SP!,{R4-R7}
% O% K$ j, q5 V8 v: H对应的微指令操作为:% [1 ^0 v/ a. F% J
[SP]    =>  R46 G# J5 R& F  J; t$ s
[SP+4]  =>  R5
* R9 C- Z8 L! s& M! X" m2 _* }6 v! v[SP+8]  =>  R6
, ~  t6 o$ z2 [' `$ C[SP+12] =>  R74 s( g5 M/ v! y3 R$ ~# t0 @' Y5 m
SP      =  SP + 16
: z8 r& {6 q4 Q
3 Y- r  x6 [0 f# X% ^+ p1 O# L- s* q0 U. A0 ^( s- [; [: m

该用户从未签到

2#
发表于 2021-9-29 14:09 | 只看该作者
在ARM的指令系统中,递减栈入栈操作的参数入栈顺序是从右到左依次入栈,而参数的出栈顺序则是从左到右的逆操作

该用户从未签到

3#
发表于 2021-9-29 16:08 | 只看该作者
一般情况下,可以将栈操作指令分解为两步微指令:数据存取和栈指针移动

该用户从未签到

4#
发表于 2021-9-29 16:22 | 只看该作者
ARM描述了四种不同类型的栈,因此对应的栈指令一共有8条
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

推荐内容上一条 /1 下一条

EDA365公众号

关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

GMT+8, 2025-11-24 00:20 , Processed in 0.171875 second(s), 26 queries , Gzip On.

深圳市墨知创新科技有限公司

地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

快速回复 返回顶部 返回列表