LDMIA、LDMIB、LDMDB、LDMDA、STMIA、LDMFD、LDMFA、LDMED、LDMEA指令详解

简介:

ARM指令中多数据传输共有两种:

LDM:(load  much)多数据加载,将地址上的值加载到寄存器上

STM:(store much)多数据存储,将寄存器的值存到地址上

主要用途:现场保护、数据复制、参数传送等,共有8种模式(前面4种用于数据块的传输,后面4种是堆栈操作)如下:

(1)IA:(Increase After) 每次传送后地址加4,其中的寄存器从左到右执行,例如:STMIA R0,{R1,LR} 先存R1,再存LR

(2)IB:(Increase Before)每次传送前地址加4,同上

(3)DA:(Decrease After)每次传送后地址减4,其中的寄存器从右到左执行,例如:STMDA R0,{R1,LR} 先存LR,再存R1

(4)DB:(Decrease Before)每次传送前地址减4,同上

(5)FD:  满递减堆栈 (每次传送前地址减4)

(6)FA:  满递增堆栈 (每次传送后地址减4)

(7)ED:  空递减堆栈 (每次传送前地址加4)

(8)EA:  空递增堆栈 (每次传送后地址加4)

注意:其中在数据块的传输中是STMMDB和LDMIA对应,STMMIA和LDMDB对应

而在堆栈操作是STMFD和LDMFD对应,STMFA和LDMFA对应

格式:

LDM{cond}  mode  Rn{!}, reglist{^}

STM{cond}  mode  Rn{!}, reglist{^}

其中

 Rn:基址寄存器,装有传送数据的起始地址,Rn不允许为R15;

 !:表示最后的地址写回到Rn中;

 reglist:可包含多于一个寄存器范围,用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大顺序排列;

 ^:不允许在用户模式和系统模式下运行

数据块的传输-实例:

Ldr R1,=0x10000000          //传送数据的起始地址0x10000000     

LDMIB R1!,{R0,R4-R6}      //从左到右加载,相当于 LDR R0,10000004  LDR R4,10000008... ...

/*传送前地址加+4,

所以地址加4,R0=0X1000004地址里的内容,

地址加4,R4=0X10000008地址里的内容,

地址加4,R5=0X1000000C地址里的内容,

地址加4,R6=0X10000010 地址里的内容,

由于!, 最后的地址写回到R1中,R1=0X10000010   */

Ldr R1,=0x10000000       //传送数据的起始地址0x10000000       

LDMIA R1!,{R0,R4-R6}         //从左到右加载,相当于 LDR R0,10000000  LDR R4,10000004... ...

/*传送后地址加+4,

所以R0=0X10000000地址里的内容,地址加4,

R4=0X10000004地址里的内容,地址加4,

R5=0X10000008地址里的内容,地址加4,

R6=0X1000000C 地址里的内容,地址加4,

由于!,最后的地址写回到R1中,所以R1=0X10000010   */

LDR R1,=0x10000000          //传送数据的起始地址0x10000000     

LDR R4,=0X10

LDR R5,=0X20

LDR R6,=0X30

STMIB R1,{R4-R6}          //从左到右加载,相当于STR [R4],0X10000004    STR [R5],0X10000008 .....

/*传送前地址加+4,所以0X10000004地址=0X10,0X10000008地址=0X20,0X1000000C地址=0X30 */

Ldr R1,=0x10000000        //传送数据的起始地址0x10000000

LDR R4,=0X10

LDR R5,=0X20

LDR R6,=0X30           

STMIA R1!,{R4-R6 }     

/*传送后地址加+4,所以0X10000000地址=0X10,0X10000004地址=0X20,0X10000008地址=0X30,由于!,最后的地址写回到R1中,所以R1=0X1000000C  */

中断实例(利用STMDB和LDMIA保护现场,然后通过LR寄存器返回) 

1.先设置栈sp,用于后面使用stmdb存储寄存器数据

2.当产生异常时,便进入中断:

sub lr, lr, #4  

 //首先将lr-4,因为arm流水线,lr=当前pc+8,由于pc+4段没有执行,所以lr=(当前pc+8)-4; stmdb sp!, { r0-r12,lr }  

//每次传送前-4,且从右往左存储寄存器

//所以sp-4=lr,sp-8=r12,... sp-56=r0; 由于!,所以最后的地址写回到sp中,sp=sp-56;

ldr lr, =int_return  //设置返回地址

ldr pc, =EINT_Handle //进入中断服务函数,如果中途返回就会调用pc=lr,即可执行int_return;

int_return: ldmia sp!, { r0-r12,pc }^  

//每次传送后+4,且从左往右加载数据到寄存器

//所以r0=sp, r1=sp+4,...pc=sp+52;由于!,所以最后地址写回到sp中,sp=sp+56;

//此时,sp=sp+56就等于最初栈顶值,pc=lr,然后返回到异常发生前的相应位置继续执行。

//^  ^表示将spsr的值复制到cpsr,因为异常返回后需要恢复异常发生前的工作状态

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏量子位

最终一战柯洁再负AlphaGo,此后再无围棋人机大战

唐旭 舒石 发自 乌镇 量子位 报道 | 公众号 QbitAI 5月27日,人机大战第三场,天气晴朗。 经过209手的博弈,主动要求执白的柯洁再次负于Alpha...

33013
来自专栏量子位

2:0!柯洁次战中盘告负AlphaGo,表现一度完美

唐旭 若朴 发自 东瑶村 量子位 报道 | 公众号 QbitAI 鏖战155手,柯洁二战AlphaGo再次落败。中盘告负。 这场比赛的激烈和复杂程度,超越双方的...

31511
来自专栏企鹅号快讯

柯洁食言“复出”再战AI:明年4月见分晓

人工智能到底有多智能?谷歌研发的人工智能程序AlphaGo此前和人类围棋第一人柯洁进行了一场人机围棋大战,不料柯洁最终没能赢过人工智能。 ? 12月11日,Go...

17110
来自专栏机器之心

现场报道 | AlphaGo被授职业九段,DeepMind将公开其所有版本细节

机器之心原创 记者:杜夏德 5 月 27 日,经过 3 小时 38 分钟的鏖战,209 手,柯洁盘中投子再负 AlphaGo,至此中国乌镇围棋峰会圆满告落。赛后...

3397
来自专栏企鹅号快讯

AlphaGo打败人类后,又打败了“自家兄弟”?

话说2017年人工智能发展的重大事件,那就是AlphaGo战胜棋手柯洁,并横扫了整个围棋界选手。在战胜柯洁后短短的五个月,谷歌deepmind团队在10月份公布...

1850
来自专栏量子位

首个围棋10段诞生!是10连胜柯洁的国产阿法狗(腾讯绝艺)

特别鸣谢量子位群友“::::::::::::::::::::::::::::::::” 量子位·QbitAI | 舒石 李林 发自 凹非寺 ? 昨晚22:32。...

4468
来自专栏镁客网

世界围棋第一人柯洁约战AlphaGo?官方回应:尚无下一步比赛计划

1467
来自专栏星流全栈

图解机器学习

1204
来自专栏镁客网

人机大战落幕: 柯洁三场全败,AlphaGo横扫人类称王

1422
来自专栏新智元

2017年AI在游戏中完胜人类,2060年通吃一切人类任务

编辑:Cecilia 【新智元导读】2017 年,AI在各种游戏中横扫人类: 在围棋比赛中,AlphaGo Master战胜世界排名最高的柯洁,随后又衍生出Al...

2614

扫码关注云+社区