ARM汇编基础
一、GNU汇编语法#
GNU 汇编语法适用于所有的架构,并不是 ARM 独享的
GNU 汇编由一系列的语句组成,每行一条语句,每条语句有三个可选部分,如下:
label:instruction@comment
label:标号,表示地址位置
instruction:指令,汇编指令或伪指令
@符号:表示后面的是注释
comment:注释内容
注意!ARM 中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用 小写,但是不能大小写混用。
使用伪操作来定义一个段,
预定义段名
.text 表示代码段。
.data 初始化的数据段。
.bss 未初始化的数据段。
.rodata 只读数据段。
默认入口标号是_start
常见的伪操作:
.byte 定义单字节数据,比如.byte 0x12。
.short 定义双字节数据,比如.short 0x1234。
.long 定义一个 4 字节数据,比如.long 0x12345678。
.equ 赋值语句,格式为:.equ 变量名,表达式,比如.equ num, 0x12,表示 num=0x12。
.align 数据字节对齐,比如:.align 4 表示 4 字节对齐。
.end 表示源文件结束。
.global 定义一个全局符号,格式为:.global symbol,比如:.global _start。
函数格式:
函数名:
函数体
返回语句
汇编函数返回语句可以省略
二、常用汇编指令#
处理器内部数据传输指令
1. MOV指令
将数据从一个寄存器拷贝到另一个寄存器,或将一个立即数传递到寄存器里面
MOV R0,R1 @将寄存器 R1 中的数据传递给 R0,即 R0=R1
MOV R0, #0X12 @将立即数 0X12 传递给 R0 寄存器,即 R0=0X12
2. MRS指令
将特殊寄存器(如 CPSR 和 SPSR)中的数据传递给通用寄存器,读取特殊寄存器的数据只能使用 MRS 指令
MRS R0, CPSR @将特殊寄存器 CPSR 里面的数据传递给 R0,即 R0=CPSR
3. MSR指令
与MRS指令相反,将普通寄存器的数据传递给特殊寄存器,写特殊寄存器只能使用MSR
MSR CPSR, R0 @将 R0 中的数据复制到 CPSR 中,即 CPSR=R0
存储器访问指令
ARM 不能直接访问存储器,用汇编配置I.MX6Q寄存器的时候需要借助存储器访问指令,一般要将配置的值写入Rx(X=0~12)寄存器中,然后借助存储器访问指令将寄存器Rx的数据写入I.MX6Q寄存器中。
1. LDR指令
从存储加载数据到寄存器Rx中,或加载一个立即数。LDR加载立即数的时候要用=,而非#。
1 LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
2 LDR R1, [R0] @读取地址 0X0209C004 中的数据到 R1 寄存器中
2. STR指令
将数据写入存储器
1 LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
2 LDR R1, =0X20000002 @R1 保存要写入到寄存器的值,即 R1=0X20000002
3 STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
压栈和出栈指令
现场保护:函数调用前保存当前处理器状态,需要进行压栈操作,指令为PUSH
恢复现场:在调用完成后恢复,进行出栈操作,指令为POP。
指令 描述
PUSH 将寄存器列表存入栈中。
POP 从栈中恢复寄存器列表。
堆栈向上增长:就是地址从低址向高地址增长。下一个存储地址比前一个地址更大。堆栈向下增长:就是地址从高地址项低地址增长。下一个存储地址比前一个地址更小。
处理器的堆栈是向下增长的
PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
PUSH {LR} @将 LR 进行压栈
POP {LR} @先恢复 LR
POP {R0~R3,R12} @在恢复 R0~R3,R12
PUSH 和 POP 的另外一种写法是“STMFD SP!”和“LDMFD SP!”
跳转指令
- 直接使用跳转指令:B、BL、BX等
- 直接向PC寄存器里面写入数据
1. B指令
将PC寄存器的值设置为跳转目标地址
1 _start:
2
3 ldr sp,=0X80200000 @设置栈指针
4 b main @跳转到 main 函数
1. BL指令
BL指令在跳转之前会在寄存器LR(R14)中保存当前PC寄存器值
1 push {r0, r1} @保存 r0,r1
2 cps #0x13 @进入 SVC 模式,允许其他中断再次进去
3
5 bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
6
7 cps #0x12 @进入 IRQ 模式
8 pop {r0, r1}
9 str r0, [r1, #0X10] @中断执行完成,写 EOIR
算数运算指令
常用加减指令
逻辑运算指令
作者:Hkhkl497
出处:https://www.cnblogs.com/hkhkl497/p/17157206.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理