简介
ARM32,也称为ARM Architecture v7,是一种32位的指令集架构(ISA),由ARM公司开发并广泛应用于嵌入式系统和移动设备。ARM32是ARM体系结构中较早的版本,被许多处理器核使用,包括Cortex-A、Cortex-R和Cortex-M系列。
ARM32架构的主要特点如下:
-
精简指令集:ARM32使用了精简指令集(RISC),指令长度固定为32位,使得指令执行更加高效。
-
可变长度指令:ARM32指令可以是16位或32位长,因此可以灵活地进行代码密度和性能的权衡。
-
寄存器:ARM32架构提供了一组寄存器,包括通用寄存器、程序计数器(PC)、堆栈指针(SP)等。这些寄存器在程序执行过程中扮演重要的角色。
-
特殊模式:ARM32架构支持不同的特殊模式,如用户模式、系统模式、中断模式等,以提供对不同操作环境的支持和保护机制。
-
条件执行:ARM32指令集支持条件执行,即指令的执行可以依赖于先前指令执行的结果和标志位的状态。
-
异常处理:ARM32具备强大的异常处理能力,可以对外部事件(如中断、故障)做出响应,并进行适当的处理。
函数调用
在ARM32架构中,函数调用参数的传递遵循一定的规则,这些规则通常由编译器实现。下面是一般情况下的函数调用参数传递规则:
- 前四个整型(1字长)或指针类型(32位地址)的参数通过寄存器传递,按照顺序依次使用R0、R1、R2和R3寄存器进行传递。
- 如果有超过四个整型或指针类型的参数,额外的参数将被依次存储在栈上,从高地址到低地址。
- 浮点参数(单精度或双精度)遵循相同的规则,但使用浮点寄存器S0、S1、S2和S3进行传递,并且多余的参数存储在栈上。
- 如果参数的大小超过一个字长(4字节),例如结构体或数组,则会将参数的地址传递给对应的寄存器或栈上的位置,而不是直接传递参数的值。
- 返回值通常通过R0寄存器返回,如果返回值大于一个字长,则额外的返回值将存储在R1寄存器或栈上。
寄存器
寄存器 | 用途 | 用法示例 |
---|---|---|
R0-R7 | 通用寄存器 用于传递参数 | MOV r0, #10 :将10移动到R0寄存器 |
R8-R12 | 通用寄存器 | ADD r10, r8, r9 :将R8和R9相加并存储到R10 |
SP | 堆栈指针 | PUSH {r0, r1, r2} :将R0、R1和R2推入堆栈 |
LR | 链接寄存器,保存返回地址 | BL subroutine :跳转到子程序subroutine,并保存返回地址 |
PC | 程序计数器,存储当前执行的指令地址 | 无 |
CPSR | 当前程序状态寄存器,保存各种标志位和模式信息 | TST r0, r1 :对R0和R1进行按位与操作并更新标志位 |
寄存器 | 用途 | 示例 | 说明 |
---|---|---|---|
S0 | 单精度浮点数 | VCVTs32F32 s0, r0 | 将整数值r0转换为单精度浮点数,并存储到S0寄存器 |
S1 | 单精度浮点数 | VADDs32 s0, s1, s2 | 将S1和S2寄存器中的浮点数相加,并将结果存储到S0寄存器 |
S2 | 单精度浮点数 | VMULs32 s0, s1, s2 | 将S1和S2寄存器中的浮点数相乘,并将结果存储到S0寄存器 |
S3 | 单精度浮点数 | VSUBs32 s0, s1, s2 | 将S1和S2寄存器中的浮点数相减,并将结果存储到S0寄存器 |
S4 | 单精度浮点数 | VLDR s0, [r0] | 从内存地址[r0]加载单精度浮点数,并存储到S0寄存器 |
S5 | 单精度浮点数 | VSTR s0, [r0] | 将S0寄存器中的单精度浮点数存储到内存地址[r0] |
S6 | 单精度浮点数 | VCMPs32 s0, s1 | 比较S0和S1寄存器中的浮点数,并设置标志位 |
S7 | 单精度浮点数 | VCVTf32s32 s0, s1 | 将S1寄存器中的整数值转换为单精度浮点数,并存储到S0寄存器 |
S8 | 单精度浮点数 | VABSs32 s0, s1 | 对S1寄存器中的浮点数取绝对值,并将结果存储到S0寄存器 |
S9 | 单精度浮点数 | VNEGs32 s0, s1 | 对S1寄存器中的浮点数求负,并将结果存储到S0寄存器 |
S10 | 单精度浮点数 | VSQRTs32 s0, s1 | 对S1寄存器中的浮点数进行平方根运算,并将结果存储到S0寄存器 |
S11 | 单精度浮点数 | VDIVs32 s0, s1, s2 | 将S1寄存器中的浮点数除以S2寄存器中的浮点数,并将结果存储到S0寄存器 |
S12 | 单精度浮点数 | VFMS32 s0, s1, s2, s3 | 执行先乘后减操作,并将结果存储到S0寄存器 |
S13 | 单精度浮点数 | VMAXs32 s0, s1, s2 | 比较S1和S2寄存器中的浮点数,将较大值存储到S0寄存器 |
S14 | 单精度浮点数 | VMINs32 s0, s1, s2 | 比较S1和S2寄存器中的浮点数,将较小值存储到S0寄存器 |
S15 | 单精度浮点数 | VMOV s0, s1 | 将S1寄存器中的浮点数复制到S0寄存器 |
指令
指令 | 说明 | 示例 |
---|---|---|
ADC | 带进位相加 | ADC r0, r1, r2 :r0 = r1 + r2 (带进位) |
ADD | 相加 | ADD r0, r1, r2 :r0 = r1 + r2 |
AND | 逻辑与 | AND r0, r1, r2 :r0 = r1 & r2 |
B | 分支到另一个位置执行 | B label :无条件分支到标签为label的位置 |
BIC | 位清除(与非) | BIC r0, r1, r2 :r0 = r1 & ~r2 |
BL | 分支并链接 | BL subroutine :分支到子程序subroutine,并保存返回地址 |
BX | 分支并切换到另一个指令集状态 | BX r0 :分支到寄存器r0所指示的地址,并切换指令集状态 |
CMN | 条件相加并更新标志位 | CMN r0, r1 :相加r0和r1并更新标志位 |
CMP | 条件比较并更新标志位 | CMP r0, #10 :比较r0和10并更新标志位 |
EOR | 异或操作 | EOR r0, r1, r2 :r0 = r1 ^ r2 |
LDM | 从内存加载多个寄存器 | LDMIA r0!, {r1, r2} :从(r0)加载r1和r2,然后递增r0 |
LDR | 从内存加载一个寄存器 | LDR r0, [r1, #4] :从(r1+4)加载数据到r0 |
MOV | 数据移动 | MOV r0, #10 :将10移动到r0寄存器 |
MUL | 乘法运算 | MUL r0, r1, r2 :r0 = r1 * r2 |
MVN | 取反操作 | MVN r0, r1 :r0 = ~r1 |
ORR | 逻辑或操作 | ORR r0, r1, r2 :r0 = r1 |
POP | 出栈操作 | POP {r0, r1, r2} :从栈中弹出r0、r1和r2 |
PUSH | 入栈操作 | PUSH {r0, r1, r2} :将r0、r1和r2推入栈 |
RSB | 反向减法 | RSB r0, r1, #0 :r0 = 0 - r1 |
SBC | 带借位减法 | SBC r0, r1, r2 :r0 = r1 - r2 - borrow |
STM | 存储多个寄存器到内存 | STMIA r0!, {r1, r2} :存储r1和r2到(r0),然后递增r0 |
STR | 存储一个寄存器到内存 | STR r0, [r1, #4] :将r0存储到(r1+4) |
SUB | 减法 | SUB r0, r1, r2 :r0 = r1 - r2 |
SWI | 软中断 | SWI 0x0 :触发软中断0x0 |
TST | 位测试操作 | TST r0, r1 :对r0和r1进行按位与操作并更新标志位 |