arm 处理器的堆栈操作
之前浏览过这篇博客的小伙伴如果需要了解ARM A32多数据处理指令恳请再过一遍这篇博客,之前由于相关知识储备不足,在从栈中恢复寄存器的指令示意图都是有问题的,在此向大家表示道歉;在此感谢向@yuth 表示感谢,感谢他帮我指出博客中的错误,帮助我加深了这一块的理解;也感谢薇远镖局,感谢他写的博客让我对此理解更加深入;感谢所有技术人对于技术的执着,只有不断探索,才能使自己的技术逐渐提升。
1 ARM堆栈操作简介
ARM 体系结构使用多寄存器的load-store指令来完成堆栈操作。
arm v7 以及ARM v8 r32 pop操作(出栈)使用一条多寄存器的load指令,push操作(入栈)使用一条多寄存器的store指令。
在使用一个堆栈的时候,需要确认堆栈在寄存器空间中是向上生长还是向下生长的。
一个堆栈或者是递增的(ascending A)------向上(高地址空间)生长,或者是递增的(descending A)------向下(低地址空间)生长。
满堆栈(Full stack F)是指堆栈指针sp只想对战的最后一个已使用的地址或满位置(也就是sp指向堆栈的最后一个数据项位置);
相反,空堆栈是指sp指向堆栈的第一个没有使用的地址或空位置(也就是sp指向对战的最后一个数据项的下一个位置)
有一些多寄存器load-store指令的别名支持堆栈操作。如下表所示在pop的右边下一列是与之等价的load指令。例如一个递增式满堆栈将由符号FA附加在load指令—LDMFA,这可以转换成一条LDMDA指令。
arm制定了ARM-Thumb过程调用标准(ATPCS),定义了历程如何被调用,寄存器如何被分配。在ATPCS
中,堆栈被定义为递减式满堆栈,因此LDMFD和STMFD指令分别用来支持pop和push功能。
2 多数据操作指令
2.1 STMFD
STMFD指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个递减式满堆栈的push操作,可以看到堆栈指针的变化,并指向堆栈的满位置。
2.2 STMED
在一个递减式空堆栈上,使用STMED指令完成的一个push操作。
STMED指令把寄存器内容压栈, sp指向了下一个空位置。
2.3 STMFA
STMFA指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个满堆栈递增式的push操作,可以看到堆栈指针的变化,并指向堆栈的满位置。
2.4 STMEA
STMEA指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个空堆栈递增式的push操作,可以看到堆栈指针的变化,并指向堆栈的空位置。
2.5 LDMED
LDMED指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个空堆栈递减式的pop操作,可以看到堆栈指针的变化,并指向堆栈的空位置。
2.6 LDMFD
LDMFD指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个满堆栈递减式的pop操作,可以看到堆栈指针的变化,并指向堆栈的满位置。
2.7 LDMEA
LDMEA指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个空堆栈递增式的pop操作,可以看到堆栈指针的变化,并指向堆栈的空位置。
2.8 LDMFA
LDMFA指令把寄存器内容放入堆栈,并更新sp的值
下图显示了在一个空堆栈递增式的pop操作,可以看到堆栈指针的变化,并指向堆栈的满位置。