分类: LINUX
2008-11-04 21:44:14
arm指令学习
一:特殊寄存器
Cpsr:状态寄存器;
R11:这个就是被称为fp frame pointer的寄存器,指向堆栈栈底,而r13指向栈顶(最外面).
R12:ip:通用临时寄存器;
R13:sp栈指针,栈顶,新的数据往这里放,它的地址是减少的,也就是往低地址长。
R14:lr连接寄存器,在子程序中指向返回地址;
R15:pc指令地址寄存器,指向当前执行的指令;
R0-r3:表示函数参数寄存器,多余4个参数的函数参数通过栈来传递;
R0:整型返回值通过r0返回;
二:条件符号:
EQ:——> == Z
NE:——> != z
CS/HS ——>进位/无符号大于或等于 C
CC/LO ——>进位清除/无符号小于 c
MI ——>负数 N
PL ——>非负数 n
VS ——>溢出 V
Vc ——>不溢出 v
HI ——>无符号大于 zC
LS ——>无符号小于 Z或c
GE ——>有符号大于或等于 NV或nv
LT ——>有符号小于 Nv或nV
GT ——>有符号大于 NzV或nzv
LE ——>有符号小于或等于 Z或Nv或nV
AL ——>无条件 忽略
三:术语解释:
算术移位:需要符号扩展;
逻辑移位:不需要符号扩展都是0;
Tst:表示&;
Cmp:表示-
TEQ:测试两个32位数是否相等;
四:一些汇编语句:
数组元素访问:int data[i]
[r2,r1,LSL#2]
其中:
R2存放的是data的首地址,
R1,存放的是i的值;
lSL,表示逻辑左移(2刚好是一个int型的四字节)
五:程序状态寄存器:
N:负标志,位31,记录标志设置操作的结果;
Z:零标志;
C:进位标志,记录无符号加法溢出,减法无借位,循环移位;
V:溢出标志;
Q:饱和标志
J:J==1表示java执行;
A:A==1表示禁止不明确的数据终止;
I:I==1表示禁止irq中断;
F:F==1表示禁止fiq中断;
T:T ==1表示thumb状态,t=0表示arm状态(默认)
六:栈:
Arm的栈是那种full型的栈也就是说栈指针(r13)指向的位置是有内容的,push之前需要先减4;
STMFD r13!,{r4,r14}
表示store to memory,也就是把r14,r4寄存器里面的值存到栈里面去,注意是反向放进去的;
LDMFD r13!,{r4,pc},这是上一条指令的相反的动作,从这里可以看出,它是从左向右的,和上一条指令相反的;也就是r14->pc
LDRD:这条指令需要8字节对齐;
注意点:
1, 在arm里面char是无符号的;
2, 用int(unsigned int)而不是其它的类型;
3, 尽量—而不是i++在循环里面;
4, 尽量不要使用局部变量的地址;
5, 函数:
a) 参数个数限制在4个以内;
b) 把调用函数和被调用函数放在一个文件中,并且要先定义再调用;
6, 结构体:
a) 把所有8位的数据放在最前面;
b) 在依次安排16位32位和64位的;
c) 把所有数组和比较大的元素放在结构体的后面;
d) 如果结构体的元素太多需要把其它的元素放在新的一个结构体中;
7除法:
a)尽量避免除法;
b)除法转化为乘法(右移);
c)环行缓冲区的访问可以不用除法,用减法;
8:pc寄存器:在程序中用到的pc值比实际的值要加2(条指令,因为流水线的缘故)