您的位置 首页 IC

ARM汇编编程根底之六-其它寻址形式与其它指令

现在我们已经掌握了所有知识,可以编写简单的ARM汇编程序,但如果要编写较为复杂的ARM程序,就必须掌握更多的寻址模式和指令,这就是本文的

现在咱们现已把握了一切常识,能够编写简略的ARM汇编程序,但假如要编写较为杂乱的ARM程序,就必须把握更多的寻址形式和指令,这便是本文的要点地点。

咱们在“根本寻址形式与根本指令”一文中学习了最常用的3种寻址方法。下面介绍其它寻址方法。

1、基址寻址

基址寻址便是将基址寄存器的内容与指令中给出的偏移量相加,构成操作数的有用地址。基址寻址用于拜访基址邻近的存储单元,常用于查表、数组操作、功用部件寄存器拜访等。基址寻址指令举例如下:

LDR R1,[R2,#0x0C]

R2的值+0x0C构成内存地址,读取内存中该地址上的内容,放入R1

其它额定需求了解的内容:

§零偏移。 如:LDR R0,[R1]

§前索引偏移。 如:LDR R0,[R1,#0x04]!,表明将R1的值加上4后作为内存地址,而且指令履行结束时,R1自身的值也要加4。这儿!表明要回写

§程序相对偏移。 如:LDR R0,labe1,表明将标号label所代表的地址处寄存的内容放入R0,相当于LDR R0, [PC, #某个常数]

§后索引偏移。 如:LDR R0,[R1],#0x04,表明将R1的值作为内存地址,而且指令履行结束时,R1自身的值要加4

2、多寄存器寻址

多寄存器寻址一次可传送几个寄存器值,答应一条指令传送16个寄存器的任何子集或一切寄存器。多寄存器寻址指令举例如下:

LDMIA R1!,{R2-R4,R6} ,它是ldr的多寄存版别,将内存中的4个字放入寄存器R2,R3,R4,R6中

指令履行前指令履行后

两点阐明:

1)、R1!中的!号表明在指令履行完结后,要改动(回写)基址寄存器(R1)的值

2)、寄存器列表{R2-R4, R6}中的次序并不要紧。终究寄存器与内存地址的对应联系是:编号小的寄存器与内存的低地址相对应

两点问题:

1)、为什么内存起地址是0x40000000,而不是0x40000004

2)、为什么内存地址是从0x40000000 —- 0x4000000C,而不是从0x3FFFFFF4 —-0x40000000

要解说上面2个问题,其实也很简略。其实多寄存加载指令ldm总共有4个:ldmia、 ldmib、 ldmda、 ldmdb。ia的意思是increase after,ib的意思是increase before,da的意思是decrease after,db的意思是decrease before。以LDMIA R1!, {R2-R4, R6}为比如,这儿的ia是指就事(将内存中的数加载到寄存器)之后添加基址寄存器(R1)的值。这条指令的履行进程从逻辑上看,如下:

1)、先就事:将R1的值(0x40000000)作为内存地址,到该地址处取得数(0x01),加载到寄存器R2中

2)、后添加:将R1的值从0x40000000添加为0x40000004

再重复上面的操作3次,别离将内存中的数0x02、0x03、0x04放到寄存器中R3、R4、R6中,最终R1的值变为0x40000010。

这个比如中,假如将ldmia改为ldmib,则R2、R3、R4、R6中寄存的是0x02、0x03、0x04、内存0x40000010处的内容,最终R1的值为0x40000010。

除了4条多寄存器加载指令外,还有4条相似的多寄存器存储指令,别离是stria、 strib、 strda、 strdb

3、仓库寻址

因为ARM指令集没有专门的出栈和入栈指令,所以ARM汇编程序是选用SP作为栈指针,以stm指令完结入栈操作,以ldm指令完结出栈操作。

以入栈后SP的值是添加仍是削减为根据,可将仓库类型划分为递加仓库(向上成长)和递减仓库(向下成长);

以SP所指向的内存处寄存的是栈顶元素仍是下一非必须入栈的元素,可将仓库类型划分为满仓库和空仓库

那么当仓库类型为空递减仓库时分,入栈操作应该运用什么指令?出栈操作应该运用什么指令?进一步,假如仓库类型为空递加、满递加、满递减仓库,又将怎么呢?假如你不看下面的答案,我相信你一定会让这几个问题折磨得做许多的脑力体操,然后感叹ARM指令集的设计者太不为你这样的程序员考虑了,给了你本不应该由你承当的负荷。但事实上正相反,ARM指令集的设计者充沛理解了你作为程序员的苦恼,请看下面的答案。

数据块传送 仓库操作 阐明
存储 压栈
STMDA STMED 空递减
STMIA STMEA 空递加
STMDB STMFD 满递减
STMIB STMFA 满递加
数据块传送 仓库操作 阐明
加载 出栈
LDMDA LDMFA 满递加
LDMIA LDMFD 满递减
LDMDB LDMEA 空递加
LDMIB LDMED 空递减

这2张表的榜首、三列答复了前面你费尽心机答复的问题。而第二列则表现了ARM指令集的设计者对作为程序员的你的充沛关心。第二列中的ED、EA、FD、FA别离表明empty descend(空递减)、 empty ascend(空递加)、 full descend(满递减)、 full ascend(满递加),其意义是说,假如你选用的是空递减(空递加、满递减、满递加)仓库的话,入栈操作则运用指令STMED(STMEA、STMFD、STMFA),出栈操作则运用指令LDMED(LDMEA、LDMFD、LDMFA)。从此你再也不会为你应该运用ia、ib、da仍是db来实现出、入栈操作而苦恼了。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/256955.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部