参考链接:https://wenku.baidu.com/view/c56f575627fff705cc1755270722192e45365885.html
LD=LoaD(加载)
ST=STore(存储)
R=Register(寄存器)
M=Move(搬运)
BIC=bit clear(位清除)
CPSR=current program status register (程序状态寄存器,用来存放当前指令执行的状态)
and=logic and (逻辑与)
eor=Logical Exclusive OR(独家的)
orr=logical or(逻辑或)
sub=subtract (减)
sbc=subtract with carry
rsb=reverse subtract (取反 减)
rsc=reverse subtract with carry
add=add (加)
adc=add with carry
tst=test
teq=Test Equivalence(等价测试)
cmp=Compare (两个值相减来设定CPRS位)
cmn=Compare Negated(取反后对比)
mvn=move negated(取反后移动)
b=branch (分支,岔路)
bl=branch with link(分支,岔路带返回值)
blx=branch with link and exchange
bx=branch and exchange
cdp=data operations
ldc=load coprocessor(加载协处理器)
mcr=move to coprocessor register(移动到协处理器)
mrc=move to arm reg from coprocessor(移动到元处理器)
MRS=move to register from state (状态寄存器到通用寄存器的传送指令)对状态寄存器CPSR和SPSR进行读操作
MSR=move to state from register (通用寄存器到状态寄存器的传送指令)对状态寄存器CPSR和SPSR进行写操作
lsl=logic shift left(左移)
asl=arithmetic shift left(算法左移)
lsr=logic shift right(右移)
asr=arithmetic shift right(算法右移)
ror=rotate right(循环(旋转)右移)
rrx=rotate right extended(循环右移,左端用进位标志位C来填充)
swp=swap (交换数据)
mul=multiply(乘)
---------------------------------------------------------------------------------------------------------------------------------------
1. ldr 加载寄存器 ldr r2, =0x7ff
例1:ldr r0,r1 //表示把r1寄存器中的值放入r0
例2:ldr r0,[r1] // [r1]表示r1中值对应内存的地址,所以是把r1中的数当作一个地址,把这个地址中的值放入r0.
后面添加 "=" 为伪指令:
例1(立即数): ldr r0, =0x12345678
例2(标号): ldr r0, =_start :将指定标号的值赋给r0
2. STR指令 用于从源寄存器中将一个32位的字数据传送到存储器中
STR R0,[R1],#8 ;将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8
( 注意:该指令特殊,是从左往右操作,其他指令都是从右往左操作。)
3. MOV指令 一般传送指令
注意:MOV
1.可以寄存器与寄存器之间传递数据
2.可以常数传递到寄存器中(常数不能超过32位)
LDR
1.可以地址与寄存器之间的数据传递
2.也可以常数传递到寄存器中
(1). r1与r2之间传递就只能用MOV: mov r1,r2
(2). 常数传递到寄存器可以使用MOV和ldr: mov r0,#0 //井号后面的,是立即数
ldr r0,=0
(3). 寄存器与地址0X00000000之间传递数据只能用ldr: ldr r0,=0X30000000
4. bp 为基址寄存器,一般在函数中用来保存进入函数时的sp的栈顶基址
sp 是栈顶指针,它每次指向栈顶。
每次子函数调用时,系统在开始时都会保存这个两个指针并在函数结束时恢复sp和bp的值。像下面这样:
在函数进入时:
push bp //保存bp指针
mov bp,sp //将sp指针传给bp,此时bp指向sp的基地址。这个时候,如果该函数有参数,则[bp+4]则是该子函数的第一个参数,[bp+6]则是该子函数的第二个参数,以此类推,有多少个参数则[bp+4+2^n]。
.....
.....
函数结束时:
mov sp,bp //将原sp指针传回给sp
pop bp //恢复原bp的值。
ret //退出子函数
5. lr=Link Register(就是连接寄存器)
(1) 是用来保存子程序返回地址;
(2) 是当异常发生时,LR中保存的值等于异常发生时PC的值减4(或者减2),因此在各种异常模式下可以;
6. cmp=Compare (两个值相减来设定CPSR位,cmp指令可以直接影响CPSR寄存器的Z标识位(条件位),比较结果为0时,Z位置1,比较结果为非0时,Z位为0;)
beq= be equal 相等为真。数据跳转指令,标志寄存器中Z标志位等于零时, 跳转到BEQ后标签处
( “beq run_on_dram” 如果 cmp r0 r1 即r0 - r1 = 0 ,程序跳转到run_on_dram处,再向下执行,此时CPSR的Z标识位为1,我们可以理解为:cmp的结果为0,或者CPSR的Z标识位为1时,程序跳转到beq 后的标签处;)
bne= be not equal 不相等为真。数据跳转指令,标志寄存器中Z标志位不等于零时, 跳转到BNE后标签处
(“bne clear_loop” 如果 r0 - r1 != 0 ,程序跳转到clear_loop处,再向下执行,此时CPSR的Z标识位为0,我们可以理解为:cmp的结果为1,或者CPSR的Z标识位为0时,程序跳转到bne 后的标签处;参考网页:https://blog.csdn.net/fanrwx/article/details/56048933)
7. PC=program counter (程序计数器)是用于存放下一条指令所在单元的地址的地方,
在执行第一条指令时,第二条指令正在译码阶段,而第三条指令正在取指阶段。在执行第一条指令时,PC寄存器应指向第三条指令。也即,当处理器为三级流水线结构时,PC寄存器总是指向随后的第三条指令。
- 当处理器处于ARM状态时,每条ARM指令为4个字节,所以PC寄存器的值为当前指令地址 + 8字节
- 当处理器处于Thumb状态时,每条Thumb指令为2字节,所以PC寄存器的值为当前指令地址 + 4字节
8. ADR =adress 是小范围的地址读取伪指令,LDR 是大范围的读取地址伪指令。
adr r1 sdram_config //sdram_config的当前地址
这条指令的反汇编为:33f80034: e28f103c add r1 ,pc ,#60(3c) //r1=r1+pc(即为34)+8+60 正好是sdram_config的地址
adr r0, _start 得到的是_start的当前执行位置,由 pc+offset 决定的 得到有效地址
ldr r0, =_start 得到的是绝对的地址,链接时决定;
可实际使用的区别是: ADR 是将基于 PC 相对偏移的地址值或基于寄存器相对地址值读取的伪指令,而 LDR 用于加载 32 位立即数或一个地址到指定的寄存器中。
ARM9 特性:PC 指向当前指令地址 +8 的位置。
9. https://blog.csdn.net/yang_niuxxx/article/details/45461149
ARM处理器CPSR标志位和条件符之间的关系
10.STMIA, 比如当前r0指向的内存地址是 0x1000,STMIA R0!,{R1-R7} 就是 首先把r1存入 0x1000,然后r2存入0x1004,然后r3存入0x1008,如果是32位的处理器就是每次加4个字节,以此类推把 r1-r7按照递增的地址存入,这个r0!就是从r0的地址开始存的意思。
STMDB则是地址从r0开始减少,依次存储。
11.LDMIA
指令:ldmia r1!, {r0-r12} 从r1中拷贝数据到r10--r12寄存器中;