ARM架构简介
1. ARM架构¶
ARM芯片属于精简指令集计算机(RISC:Reduced Instruction Set Computing),它所用的指令比较简单,有如下特点:
① 对内存只有读、写指令
② 对于数据的运算是在CPU内部实现
③ 使用RISC指令的CPU复杂度小一点,易于设计
2. CPU寄存器¶
无论是cortex-M3/M4,
还是cortex-A7,
CPU内部都有R0、R1、……、R15寄存器;
它们可以用来“暂存”数据。
对于R13、R14、R15,还另有用途:
R13:别名SP(Stack Pointer),栈指针
R14:别名LR(Link Register),用来保存返回地址
R15:别名PC(Program Counter),程序计数器,表示当前指令地址,写入新值即可跳转
3. CPU计算¶
CPU计算 a=a+b 的过程:
4. 常见汇编指令¶
4.1 栈操作指令¶
PUSH :压栈,将寄存器的内容压入栈中。
例如:PUSH {r2, lr}
为将r2
、lr
寄存器的值压入栈空间
POP :出栈,将 栈顶 的数据弹出,并恢复寄存器的值。
例如:POP {r2-r3, pc}
4.2 寄存器赋值¶
MOV :给寄存器赋值,不影响标志寄存器。
例如:MOV R0, #0x10
将 0x10
传送到寄存器 R0
。
MOVS :给寄存器赋值,并更新状态标志。
例如:MOVS r0, #0x0A
将0x0A
赋值给r0
寄存器,并更新条件码标志(如零标志、进位标志等)。
MOVW :将一个 16 位的立即数加载到寄存器中。
例如:MOVW R0, #0x1234
将 0x1234
传送到 R0
寄存器 的低 16 位。
4.3 写寄存器¶
STR :将寄存器中的4个字节数据写入内存。
例如:STR r0, [sp, #0x00]
将r0
寄存器的值写入栈指针sp
偏移0x00
位置的内存。
STRB :将寄存器中的1个字节写入内存。
例如:STRB r0, [sp, #0x00]
将r0
寄存器的最低字节(1字节)写入栈指针sp
偏移0x00
位置的内存。
STRH :将寄存器中的2个字节写入内存。
例如:STRH r0, [sp, #0x00]
将r0
寄存器的低16位写入栈指针sp
偏移0x00
位置的内存。
4.4 读寄存器¶
LDR :从内存读取4个字节数据到寄存器。
例如:LDR r0, [sp, #0x00]
将栈指针sp
偏移0x00
位置的4个字节数据读取到r0
寄存器。
LDRB :从内存读取1个字节数据到寄存器。
例如:LDRB r0, [sp, #0x00]
将栈指针sp
偏移0x00
位置的1字节数据读取到r0
寄存器。
LDRH :从内存读取2个字节数据到寄存器。
例如:LDRH r0, [sp, #0x00]
将栈指针sp
偏移0x00
位置的2字节数据读取到r0
寄存器。
LDRD :从内存读取8个字节数据到寄存器。
例如:LDRD r1, r0, [sp, #0x00]
将栈指针sp
偏移0x00
位置的8字节数据读取到r0
和r1
寄存器。
4.5 加减指令¶
ADD :加法操作。
例如:ADD r0, r0, r1
将r0 = r0 + r1
,将r0
和r1
寄存器的值相加,并将结果存入r0
。
SUB :减法操作。
例如:SUB sp, sp, #0x68
将栈指针sp
减去0x68
,即sp = sp - 0x68
,用于在栈上分配或释放空间。
4.6 跳转与调用指令¶
B :无条件跳转。
例如:B label
跳转到标签label
,执行该位置的代码。
BL :带返回地址的跳转(用于函数调用)。
例如:BL subroutine
跳转到subroutine
函数,并将返回地址(跳转指令后的地址)保存到lr
(链接寄存器)。函数执行完毕后,通过POP
或其他机制恢复pc
来返回。
4.7 其他常见指令¶
NOP :空操作指令。不会做任何事情,仅用于占位或调试。
例如:NOP
占用一个时钟周期,但不改变任何寄存器或标志。
CMP :比较两个寄存器或值。
例如:CMP r0, r1
将r0
和r1
进行比较,更新条件码,但不保存结果。
TST :按位与运算,用于检查特定位的状态。
例如:TST r0, #0x1
将r0
与0x1
进行按位与,检查最低位是否为1。