Loading

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
算数运算指令

常用加减指令

逻辑运算指令

 

posted @ 2023-02-26 21:22  Hkhkl497~  阅读(53)  评论(0)    收藏  举报