为什么需要汇编?
- C语言中的函数调用涉及到出栈入栈,出栈入栈就要 对堆栈进行操作,所谓的堆栈其实就是一段内存,这段内存比较特殊,由SP指针访问, SP指 针指向栈顶。芯片一上电SP指针还没有初始化,所以 C语言没法运行。
- 对于有些芯片还需要 初始化 DDR,因为芯片本身没有 RAM,或者内部 RAM不开放给用户使用,用户代码需要在 DDR中运行,因此一开始要用汇编来初始化 DDR控制器。
总而言之,我们需要在芯片上电以后用汇 编来初始化一些外设,已完成C语言运行的要求,不会涉及到复杂的代码。
GNU汇编语法
我们编译ARM架构的代码,都是在Linux上使用gcc交叉编译器,所以使用的ARM汇编也是符合GNU汇编的语法要求的。
指令语句
GNU每行一个语句,语句格式为:label: instruction @ comment
- label:标号,表示指令的地址,也可以表示数据地址
- instruction:汇编指令或伪指令。指令可以大写或小写
-
指令段
每个指令段以段名开始,以下一段名或文件结尾为结束,格式为:
.section .name
.section:伪操作关键字
- .name:可以是自定义的段名,也可以是下面预定义的:
_start: ldr r0, =0x12 @r0=0x12
<a name="B7Nuh"></a>
## 伪操作
常见的伪操作有:
- .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
<a name="8vQnW"></a>
## 汇编函数
定义函数的格式如下,其中返回语句不是必须的:
函数名 : 函数体 返回语句 ```