一、学习ARM汇编的目的
核心目的:编写ARM启动代码
启动代码5大任务:
- 初始化异常向量表
- 初始化各处理器工作模式的栈指针寄存器
- 开启ARM内核中断允许
- 将处理器工作模式设置为User用户模式
- 完成初始化,引导程序进入C语言
main函数
二、移位指令
- LSR 逻辑右移:最高位补0,适用于无符号数
- ASR 算术右移:最高位补符号位,适用于有符号数
- ROR 循环右移:移出的最低位补到最高位
- LSL 逻辑左移
三、基础数据传送与运算指令
1. MOV 数据传送
MOVS <Rd>, #<imm8> ;把立即数赋值给寄存器
MOV{S}<c> <Rd>, <Rm> ;寄存器之间拷贝
S后缀:执行后会更新CPSR状态标志位。
2. ADD 加法指令
ADD{S}<c> <Rd>, <Rn>, #<const> ;寄存器+立即数
ADD{S}<c> <Rd>, <Rn>, <Rm> ;寄存器+寄存器
ADD{S}<c> <Rd>, <Rn>, <Rm>,<type> <R> ;运算同时带移位操作
3. 12位立即数判断规则
- 数值在 0~0xFF(255),一定是合法立即数;
- 二进制最高位1到最低位1之间有效序列不能超过8位;
- 有效8位序列右侧必须有偶数个连续0。
四、内存读写指令 LDR / STR
LDR:加载,把数据从内存读到寄存器
ldr r0,=0x12345678:伪指令,把大立即数加载到寄存器ldr r0,=0x40000000:把内存地址放入寄存器ldr r1,[r0]:把r0指向内存地址的数据读取到r1,等价r1 = *r0
STR:存储,把寄存器数据写入内存
str r1, [r0] ; *r0 = r1
str r1, [r0, #4] ; *(r0+4) = r1,基址偏移,地址寄存器不改变
str r1, [r0], #4 ; *r0 = r1 ; r0=r0+4,事后自增
str r1, [r0, #4]! ; r0=r0+4 ; *r0 = r1,!代表先修改基址寄存器
五、位操作指令
- ORR:将某个通用寄存器置1(操作数中为bit1的位置1),置1结果写回到通用寄存器
orr r0, r0, #(1 << 7) ;把r0第7位设置为1
- BIC:将某个通用寄存器清0(操作数中为bit1的位清0),清0结果写回到通用寄存器
bic r0, r0, #(1 << 7) ;把r0第7位清0
六、比较与跳转指令
- CMP Rn,Rm:比较两个寄存器,做减法运算,只更新CPSR标志位,不保存运算结果。
- B:无条件跳转;配合条件后缀
blt(小于跳转)、bgt(大于跳转)实现分支判断。 - BL:带返回地址跳转,跳转前把返回地址保存到LR(R14)寄存器,用于函数调用。
- BX LR:函数返回,等价
mov pc,lr,跳转到LR保存的返回地址。
七、ARM栈操作
ARM使用满减栈:SP指向有效的栈元素,入栈先减小SP,再存数据。
- STMFD sp!,{r0,r1,lr}:入栈保护寄存器,把多个寄存器压入栈
- LDMFD sp!,{r0,r1,lr}:出栈恢复寄存器,从栈读取数据回寄存器
!:表示执行指令后更新SP寄存器的值。
八、汇编与C语言混合编程
汇编调用C函数
- 参数 ≤4:使用R0~R3传递参数;
- 参数 >4:参数压栈,通过栈传递;
- C函数返回值存放于 R0。
C调用汇编函数
- C传入的参数自动存入R0‑R3;
- 汇编函数的返回结果,通过R0返回给C程序。
九、特殊寄存器读写 & 切换User模式
MRS、MSR专门访问CPSR/SPSR这类特殊状态寄存器,普通MOV指令不能操作。
- MRS Rd,cpsr:读,把CPSR的值读到通用寄存器Rd
- MSR cpsr,Rd:写,把通用寄存器Rd的值写入CPSR
切换到User用户模式三步流程:
mrs r0,cpsr:读取CPSR当前状态到r0- 修改r0的模式位,设置为User模式对应编码
10000 msr cpsr,r0:将修改后的值写回CPSR,完成模式切换。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/SXR0115/article/details/165622904




