arm汇编指令整理
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): 空递增堆栈;
{^}有两种含义:如果
指令中寄存器列表和内存单元的对应关系为:编号低的寄存器对应于内存中的低地址单元,编号高的寄存器对应于内存中高地址的单元。
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,这样这两个操作就可以成功配对。
在寄存
ARM汇编指 相关文章:
- ARM汇编指令的一些总结(11-28)
- 常用ARM汇编指令(11-28)
- 第1天-ARM汇编指令ADD/SUB/MUL(11-26)
- 第1天-ARM汇编指令CMP/CMN/TST/TEQ(11-26)
- 第1天-ARM汇编指令B/BL(11-26)
- 第1天-ARM汇编指令MOV/MVN(11-26)