4.简单的 GNU 汇编语法
芯片启动时很多设备没有初始化,需要汇编语言进行准备。
简单的GNU汇编语法:
1 label: instruction @ comment
label :标号,类似于外号,为所在位置做标号,可以通过这个标号访问这里的内容 所有的以“:”结尾的都被认为是标号
instruction : 指令,包含汇编指令和伪指令
comment : 注释部分 ,在“@”后面的被认为是注释,也可以用类似于C语言的 “/*” 和“*/”
ARM 中的指令、伪指令、伪操作、寄存器名等可以全部使用大写,也可以全部使用小写,但是不能大小写混用。
用户可以使用.section 伪操作来定义一个段,汇编系统预定义了一些段名:
.text 代码段
.data 数据段(初始化的)
.bss 数据段(未初始化的)
.rodata 只读数据
我们可以自己使用.section 来定义一个段,每个段以段名开始,以下一段名或者文件结尾结束,比如:
1 .section .testsection @定义一个 testsetcion 段(text/data/bss/rodata)
汇编程序的默认入口标号是_start,不过我们也可以在链接脚本中使用 ENTRY 来指明其它的入口点
下面的代码就是使用_start 作为入口标号:
1 global _start 2 3 _start: 4 ldr r0, =0x12 @r0=0x12
上面代码中.global 是伪操作,表示_start 是一个全局标号,类似 C 语言里面的全局变量一样
常见的伪操作有:
GNU 汇编同样也支持函数,函数格式如下:
1 函数名: 2 函数体 3 返回语句 @非必须
代码类似于:
1 /* 未定义中断 */ 2 Undefined_Handler: 3 ldr r0, =Undefined_Handler 4 bx r0 5 6 7 /* SVC 中断 */ 8 SVC_Handler: 9 ldr r0, =SVC_Handler 10 bx r0 11 12 13 /* 预取终止中断 */ 14 PrefAbort_Handler: 15 ldr r0, =PrefAbort_Handler 16 bx r0
Cortex-A7常用汇编指令
1、处理器内部数据传输指令
2、存储器访问指令
3、压栈出栈指令
例如:
1 PUSH {R0~R3, R12} @将 R0~R3 和 R12 压栈
PUSH 和 POP 的另外一种写法是“STMFD SP!”和“LDMFD SP!”
1 STMFD SP!,{R0~R3, R12} @R0~R3,R12 入栈 2 STMFD SP!,{LR} @LR 入栈 3 4 LDMFD SP!, {LR} @先恢复 LR 5 LDMFD SP!, {R0~R3, R12} @再恢复 R0~R3, R12
4、跳转指令
5、算术运算符
6、逻辑运算指令