伪操作.section 【段名】
.text代码段
.data数据
.bss未初始化
.rodata只读
.section .textsection @定义一个数据段
--------------------------------------其他伪操作
.byte 定义单字节数据,比如.byte 0x12
.short 定义双字节数据,比如.byte 0x1234。
.long 定义一个 4 字节数如.long0x12345678。
.equ 表达式,比如.equ num, 0x12 num=0x12
.align 数据字节对齐,比如:.align 4 表示 4 字节对齐
.end 表示源文件结束
.global 定义一个全局符号,格式为:.global symbol,比如:.global _start。
--------------------------------GNU 汇编同样也支持函数
/* 未定义中断 */
Undefined_Handler:
ldr r0, =Undefined_Handler
bx r0
/* SVC 中断 */
SVC_Handler:
ldr r0, =SVC_Handler
bx r0
/* 预取终止中断 */
PrefAbort_Handler: @函数名字
ldr r0, =PrefAbort_Handler @函数体
bx r0 @常用返回语句,非必须
--------------------------------------------1、处理器内部数据传输指令
使用处理器做的最多事情就是在处理器内部来回的传递数据,常见的操作有:
①、将数据从一个寄存器传递到另外一个寄存器。
MOV R1,R2
②、将数据从一个寄存器传递到特殊寄存器,如 CPSR 和 SPSR 寄存器。
MRS R0,CPSR
或者:MSR CPSR,R1
③、将立即数传递到寄存器。
MOV R1,#0X12
----------------------------------------2、储存器访问指令 RAM
从存储器 Rn+offset 的位置读取数据存放到 Rd 中
LDR Rd,[Rn,#offset] @eg:
LDR R0,=0X0209C004@将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1,[R0]@读取地址 0X0209C004 中的数据到 R1 寄存器中
将 Rd 中的数据写入到存储器中的 Rn+offset 位置。
STR Rd,[Rn,#offset]
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, =0X20000002 @R1 保存要写入到寄存器的值,即 R1=0X20000002
STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
--------------------------------3、压栈和出栈
PUSH
POP
PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
PUSH {LR}
POP {LR} @先恢复 LR
POP {R0~R3,R12} @在恢复 R0~R3,R12
第二种写法: FD 是 Full Descending 的缩写,即满递减的意思。
STMFD SP! LDMFD SP!
STMFD SP!,{R0~R3, R12} @R0~R3,R12 入栈 右边高地址
STMFD SP!,{LR} @LR 入栈
LDMFD SP!, {LR} @先恢复 LR
LDMFD SP!, {R0~R3, R12} @再恢复 R0~R3, R12
--------------------------------------------4、跳转指令
B
_start:
ldr sp,=0X80200000 @设置栈指针
b main @跳转到 main 函数
B.W
BX
BL
push {r0, r1} @保存 r0,r1
cps #0x13 @进入 SVC 模式,允许其他中断再次进去
bl system_irqhandler @加载 C 语言中断处理函数到 r2 寄存器中
cps #0x12 @进入 IRQ 模式
pop {r0, r1}
str r0, [r1, #0X10] @中断执行完成,写 EOIR
BLX
址保存在 LR 中,切换指令集。
--------------------------------------------------5、算数指令
ADD Rd,Rn,Rm @ Rd=Rn+Rm
DD Rd, Rn, #immed @Rd = Rn + #immed
ADC Rd, Rn, Rm Rd = Rn + Rm + 进位
ADC Rd, Rn, #immed Rd = Rn + #immed +进位
SUB Rd, Rn, Rm @Rd = Rn – Rm
SUB Rd, #immed @Rd = Rd - #immed
SUB Rd, Rn, #immed @Rd = Rn - #immed
SBC Rd, Rn, #immed Rd = Rn - #immed – 借位
SBC Rd, Rn ,Rm Rd = Rn – Rm – 借位
MUL Rd, Rn, Rm Rd = Rn * Rm 乘法(32 位)
UDIV Rd, Rn, Rm Rd = Rn / Rm 无符号除法
SDIV Rd, Rn, Rm Rd = Rn / Rm 有符号除法
----------------------------------------------6、逻辑指令
AND Rd, Rn @ Rd = Rd &Rn
AND Rd, Rn, #immed @Rd = Rn immed
AND Rd, Rn, Rm @Rd = Rn & Rm
ORR Rd, Rn @Rd = Rd | Rn
ORR Rd, Rn, #immed @Rd = Rn | #immed
ORR Rd, Rn, Rm @Rd = Rn | Rm
BIC Rd, Rn @Rd = Rd & (~Rn) 位清除
BIC Rd, Rn, #immed @Rd = Rn & (~#immed)
BIC Rd, Rn , Rm @Rd = Rn & (~Rm)
ORN Rd, Rn, #immed @Rd = Rn | (w#immed) 按位或非
ORN Rd, Rn, Rm Rd = Rn | (wRm)
EOR Rd, Rn Rd = Rd ^ Rn按位异或
EOR Rd, Rn, #immed Rd = Rn ^ #immed
EOR Rd, Rn, Rm Rd = Rn ^ Rm
-----------------------------------
DSB 数据同步
ISB 指令同步-
--------------------------------------------
MRC: 将 CP15 协处理器中的寄存器数据读到 ARM 寄存器中。
MRC 就是读 CP15 寄存器, MCR 就是写 CP15 寄存器,MCR 指令格式如下:
MCR{cond} p15, , ,, ,
MRC p15, 0, r0, c0,c0,0
现在要关闭I,D ache和MMU,打开Cortex-A7参考手册到105页,找到SCTLR寄存器。也就是系统控制寄存器,此寄存器bit0用于打开和关闭MMU,bit1控制对齐,bit2控制D Cache的打开和关闭。Bit11用于控制分支预测。Bit12用于控制I Cache。
中断向量偏移设置
将新的中断向量表首地址写入到CP15协处理器的VBAR寄存器。
MCR{cond} p15, , , , ,
MRC p15,0,r0,c12,c0,0 //
MCR p15,0,r0,c12,c0,0
-------------------------------------------
ldr r0 ,[r1 ,#0xc]
-----------------------------------------
cps #0x13 模式切换为SVC