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

ARM的栈与栈指令

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
一、定义:栈(Stack)是限定仅在一端进行插入或删除操作的线性表。
( m$ a7 q$ q9 `( h4 M7 Y4 m因此,对栈来说,可以进行插入或删除操作的一端端称为栈顶(top),相应地,另一端称为栈底(bottom)。不含元素的空表称为空栈。由于堆栈只允许在一端进行操作,因而按照后进先出(LIFO-Last In First Out)的原理运作。从栈顶的定义来看,栈顶的位置是可变的。空栈时,栈顶和栈底重合;满栈时,栈顶离栈底最远。ARM为堆栈提供了硬件支持,它使用一个专门的寄存器(堆栈指针)指向堆栈的栈顶。而且7种模式都有各自独立的堆栈指针,也就是有各自独立的堆栈空间。
) d7 L9 s/ h0 N  `5 h& L二、如何描述一个栈
$ A( `% K- K0 x; ^准确描述一个栈的特点需要两个参数1 ~4 a2 X3 M: A: e/ ~" D
栈地址的增长方向:ARM将向高地址增长(也叫做向上增长)的栈称为递增栈(ascendant Stack),将向低地址增长(也叫做向下增长)的栈称为递减栈(descendantStack)( @( I6 y  {8 \
栈指针的指向位置:ARM将栈指针指向栈顶元素位置的栈称为满栈(Full Stack),讲栈指针指向即将入栈的元素位置的栈称为空栈(Empty Stack)" l5 s2 h6 \9 ?5 s( w
根据栈地址增长方向雨栈指针指向位置的不同,自然可以将栈分为四类:( F1 |. Z! U" A. p/ f

' A8 Z' s- G. E( A! K下图描述了四种不同类型的栈,其中虚线部分表示即将入栈的元素。
' a9 q3 K; {1 b/ ~8 |

$ x7 {' b5 c; G三、栈指令
$ a8 ?( M; I/ `6 ~! U. T5 D: e" Q% O栈的操作指令无非两种:入栈和出栈,由于ARM描述了四种不同类型的栈,因此对应的栈指令一共有8条。
1 \7 ^: q0 U. f* n; n, c
STM:(STore Multiple data)表示存储数据,即入栈。' u5 l0 B  w7 U) A+ L6 R( `# U4 d5 M
LDM:(LoaD Multiple data)表示加载数据,即出栈。7 f# y. N5 j# Z  q. U6 t
一般情况下,可以将栈操作指令分解为两步微指令:数据存取和栈指针移动。这两步操作的先后顺序和栈指针的移动方式由栈的类型决定。
2 y1 |1 }& h! j& m/ e6 ?
8 ]; F5 N# R- iARM中存在一组缓冲区操作指令和栈指令是一一对应的,他们完成相同的功能。这些指令含义的区别来源于对存取操作的缓冲区指针地址增长方向,以及存取操作和缓冲区指针移动的先后顺序决定的。这个和前面描述的栈类型的分类原则十分相似。" E+ E0 K" D) }
) z0 g: x- _6 N6 d0 M) e
四、实例8 V) R& m! B2 D) t5 w( u4 K* z
虽然ARM的栈类型和相关的操作指令比较繁琐,但是实际上最常用的还是和x86指令集相同的栈类型:栈向低地址方向增长,且栈指针指向栈顶元素的位置,即ARM的FD栈。因此最常见的ARM栈指令操作是STMFD和LDMFD。
0 C2 o  q& f$ C3 J例如入栈指令:3 e+ E5 Q  ]. F8 G9 t
STMFD SP,{R0-R3}2 X8 l5 y5 [: S/ d4 ~3 R3 \8 C
实际的微指令操作为:- P8 W1 v4 o4 @7 ]
[SP-4]  <=  R3
& m& z, M1 _- r  K6 p$ X. O[SP-8]  <=  R2
* f+ l* C% P# ?2 s% L" Q6 Q4 |[SP-12] <=  R1
; S$ q2 P" `' L+ h5 X: {[SP-16] <=  R0
# {) O# \1 x/ b; y% T5 p在ARM的指令系统中,递减栈入栈操作的参数入栈顺序是从右到左依次入栈,而参数的出栈顺序则是从左到右的逆操作。对于递增栈,相应的操作则全部取反。
$ A0 V, e; A% A& t2 h, W' |* d- V& b例如出栈指令:
, u9 s  c$ c! JLDMFD SP,{R4-R7}
. B) ]$ G/ y  q$ a8 I; L: }- w8 z实际的微指令操作为:% y) U4 Z4 M3 c7 V' x4 J; H
[SP]    =>  R4
( f4 U7 A, I* N5 Z) S. X[SP+4]  =>  R5
+ j+ h9 M8 Y; V; W+ |  f[SP+8]  =>  R6
. t5 `' O! ?  T1 s: W  g[SP+12] =>  R7( U- K# l8 N( n( N7 }% C
上述的入栈和出栈指令其实仅仅对栈做了存取操作,并未真正改变SP指针的值。正常情况下,我们希望对栈操作后能自动修改栈指针SP的值,使用如下指令可以达到该目的。# |  o( k# T0 c9 T1 C8 E
STMFD SP!,{R0-R3}
6 `2 e% L' J  A1 S对应的微指令操作为:# x& z! v4 ~1 ~& }4 Y+ l: u
[SP-4]  <=  R3% e, K8 ?6 x: J# h+ y
[SP-8]  <=  R2
4 M/ J4 U# ~0 X6 t7 H[SP-12] <=  R1
* Q5 Z5 w# |# H[SP-16] <=  R05 ~3 I0 P9 G! ]; l0 r2 r" m3 K
SP      =  SP - 16
+ @! {. N; ?' O4 g0 r) W/ i5 |  ]同样的:% }" s7 h& x! p* m3 `
LDMFD SP!,{R4-R7}
2 D+ Q$ d* y& Q# {4 o对应的微指令操作为:
4 \  W5 ?# ~1 l5 D+ [  m[SP]    =>  R4% }3 f4 D6 v, o4 {- _
[SP+4]  =>  R5) y2 B; {" z# p3 X* X+ O
[SP+8]  =>  R6
4 _& T& p* e" b! a7 T: R2 M2 W[SP+12] =>  R7
' ]# @' ~" Q: O* Q1 W5 k9 vSP      =  SP + 16% ?5 b! X+ J" F( k; }
, D  \% N% P8 ^2 r# @

0 b6 g% o0 Y! U# e( I; W( d

该用户从未签到

4#
发表于 2021-9-29 16:22 | 只看该作者
ARM描述了四种不同类型的栈,因此对应的栈指令一共有8条

该用户从未签到

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

该用户从未签到

2#
发表于 2021-9-29 14:09 | 只看该作者
在ARM的指令系统中,递减栈入栈操作的参数入栈顺序是从右到左依次入栈,而参数的出栈顺序则是从左到右的逆操作
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 02:27 , Processed in 0.156250 second(s), 27 queries , Gzip On.

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

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

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