微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm汇编指令整理

arm汇编指令整理

时间:11-09 来源:互联网 点击:

dr r0, _strt

取得 _start 的地址到 r0,但是请看反编译的结果,它是与位置无关的。其实取得的时相对的位置。例如这段代码在 0x0c008000 运行,那么 adr r0, _start 得到 r0 = 0x0c008014;如果在地址 0 运行,就是 0x00000014 了。

ldr r0, =_start

这个取得标号 _start 的绝对地址。这个绝对地址是在 link 的时候确定的。看上去这只是一个指令,但是它要占用 2 个 32bit 的空间,一条是指令,另一条是 _start 的数据(因为在编译的时候不能确定 _start 的值,而且也不能用 mov 指令来给 r0 赋一个 32bit 的常量,所以需要多出一个空间存放 _start 的真正数据,在这里就是 0x0c008014)。

因此可以看出,这个是绝对的寻址,不管这段代码在什么地方运行,它的结果都是 r0 = 0x0c008014

11.ldm

ldm和stm属于批量内存访问指令,只用一条指令就可以读写多个数据。它们的格式如下:

ldm{cond} {!} {^}

stm{cond} {!} {^}

其中,

{cond}表示指令的执行条件,参见下面的指令条件码。

表示地址变化模式,有以下几种方式:

1)ia(increment after): 传送后递增方式;

2)ib(increment before): 传送前递增方式;

3)da(decrement after): 传送后递减方式;

4)db(decrement before):传送前递减方式;

5)fd(full descending): 满递减堆栈;

6)ed(empty descending):空递减堆栈;

7)fa(full ascending): 满递增堆栈;

8)ea(empty ascending): 空递增堆栈;

中保存内存的地址,如果后面加上了感叹号,指令执行后,rm的值会更新,等于下一个内存单元的地址。

表示寄存器列表,对于ldm指令,从所对应的内存块中取出数据,写入这些寄存器;对于stm指令,把这些寄存器的值写入所对应的内存块中。

{^}有两种含义:如果中有PC寄存器,它表示指令执行后,spsr寄存器的值将自动到cpsr寄存器中——这常用于从中断处理函数中返回;如果中没有PC寄存器,{^}表示操作的是用户模式下的寄存器,而不是当前特权模式的寄存器。

指令中寄存器列表和内存单元的对应关系为:编号低的寄存器对应于内存中的低地址单元,编号高的寄存器对应于内存中高地址的单元。

ldmia r0!, {r3-r10} /*将基址寄存器r0开始的连续8个地址单元的值分别赋给r3,r4,r5,r6,r7,r8,r9,r10,注意的是r0指定的地址每次赋一次r0会加1,指向下一个地址单元*/

stmia r1!, {r3-r10} /*跟上面指令功能相反,将寄存器r3到r10的值依次赋值给r1指定的地址单元,每次赋值一次r1就加1*/

堆栈寻址:堆栈是特定顺序进行存取的存储区,堆栈寻址时隐含的使用一个专门的寄存器(堆栈指针),指向一块存储区域(堆栈),存储器堆栈可分为两种:

向上生长:向高地址方向生长,称为递增堆栈。
向下生长:向低地址方向生长,称为递减堆栈。

如此可结合出四种情况:
1、满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址,栈指针总是指向最后一个元素(最后入栈的数据),指令如 LDMFA,STMFA。
2、空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置,栈指针总是指向下一个将要放入数据的空位置,指令如 LDMEA,STMEA。
3、满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址,栈指针总是指向最后一个元素(最后入栈的数据),指令如 LDMFD,STMFD。
4、空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置,栈指针总是指向下一个将要放入数据的空位置,指令如 LDMED,STMED。

满:栈指针总是指向最后一个元素(最后入栈的数据)。

空:栈指针总是指向下一个将要放入数据的空位置。

增:栈首部是低地址,栈向高地址增长。

减:栈首部是高地址,栈向低地址增长。

STMFD SP!,{R1-R7,LR} ;将R1-R7,LR入栈,满递减堆栈
LDMFD SP!,{R1-R7,LR} ;数据出栈,放入R1-R7,LR寄存器,满递减堆栈

ARM-Thumb过程调用标准和ARM、Thumb C/C++ 编译器总是使用Full descending 类型堆栈。

以前困惑的就是STMFD 命令 对于操作数 是按照什么顺序压栈的

比如:STMFD sp!{R0-R5,LR} 进栈顺序是:

高地址(1方式) LR R5 R4 ``````` R0 <-sp 低地址

高地址(2方式) R0 R1 ``` R5 LR <-sp 低地址

寻址方式

说明

pop

=LDM

push

=STM

FA

递增满

LDMFA

LDMDA

STMFA

STMIB

FD

递减满

LDMFD

LDMIA

STMFD

STMDB

EA

递增空

LDMEA

LDMDB

STMEA

STMIA

ED

递减空

LDMED

LDMIB

STMED

STMDA

按照图表,可知 STMFD对应的是STMDB,根据arm指令手册,可知STMDB入栈顺序是1方式,而LDMFD对应的是LDMIA,这样这两个操作就可以成功配对。

在寄存

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top