目录
1 伪指令
2 伪操作
3 C和汇编的混合编程
4 ATPCS协议
1 伪指令
本身不是指令,编译器可以将其替换成若干条等效指令
@ 空指令NOP@ 指令LDR R1, [R2]@ 将R2指向的内存空间中的数据读取到R1寄存器@ 伪指令LDR R1, =0x12345678@ R1 = 0x12345678 @ LDR伪指令可以将任意一个32位的数据放到一个寄存器LDR R1, =STOP@ 将STOP表示的地址写入R1寄存器@ LDR R1, STOP@ 将STOP地址中的内容写入R1寄存器
2 伪操作
不会生成代码,只是在编译之前告诉编译器怎么编译
@ GNU的伪操作一般都以‘.’开头@ .global symbol@ 将symbol声明成全局符号@ .local symbol@ 将symbol声明成局部符号@ .equ DATA, 0xFF@ MOV R1, #DATA@ 相当于define@ .macro FUNC@ MOV R1, #1@ MOV R2, #2@ .endm@ FUNC@ .macro 相当于函数封装@ .if 0@ MOV R1, #1@ MOV R2, #2@ .endif@.rept 3@ MOV R1, #1@ MOV R2, #2@.endr@ .weak symbol@ 弱化一个符号,即告诉编译器即便没有这个符号也不要报错@ .weak func@ B func@ .word VALUE@ 在当前地址申请一个字的空间并将其初始化为VALUE@ MOV R1, #1@ .word 0xFFFFFFFF@ MOV R2, #2@ .byte VALUE @ 在当前地址申请一个字节的空间并将其初始化为VALUE@ MOV R1, #1@ .byte 0xFF@ .align N@ 告诉编译器后续的代码2的N次方对其@ .align 4@ MOV R2, #2@ .arm@ 告诉编译器后续的代码是ARM指令@ .thumb@ 告诉编译器后续的代码是Thumb指令@ .text @ 定义一个代码段@ .data @ 定义一个数据段@ .end 之前的代码都是汇编代码@ .space N, VALUE@ 在当前地址申请N个字节的空间并将其初始化为VALUE@ MOV R1, #1@ .space 12, 0x12@ MOV R2, #2@ 不同的编译器伪操作的语法不同
rept示例
.word示例
.byte示例
.align 2代表对齐,2代表2的2次方对齐,即4的整数倍。如果3代表8的整数倍。
3 C和汇编的混合编程
通用寄存器指令
- 1、数据处理指令
- 2、跳转指令
- 3、内存读写指令load
Arm专用指令,不会有C语言与之对应
- 4、CPSR
- 5、SWI
- 6、协处理器指令
上电的第一段代码都是用汇编写的。
@ C和汇编的混合编程原则:在哪种语言环境下符合哪种语言的语法规则@ 1. 在汇编中将C中的函数当做标号处理@ 2. 在C中将汇编中的标号当做函数处理@ 3. 在C中内联的汇编当做C的语句来处理@ 1. 方式一:汇编语言调用(跳转)C语言@ MOV R1, #1@ MOV R2, #2@ BL func_c @func_c用c写,最后会通过LR跳转回来,不写括号@ MOV R3, #3@ 2. 方式二:C语言调用(跳转)汇编语言@ .global FUNC_ASM @必须加.global否则c文件中不认识
@ FUNC_ASM:@ MOV R4, #4@ MOV R5, #5void func_c(void){int a;a ++;//C语言调用(跳转)汇编语言FUNC_ASM(); //需要括号a --;}@ 3. C内联(内嵌)汇编/*
void func_c(void)
{int a;a ++;//C内联(内嵌)汇编asm("MOV R6, #6\n""MOV R7, #7\n");//C语言调用(跳转)汇编语言FUNC_ASM();a --;
}
*/
4 ATPCS协议
@ ATPCS协议主要内容 @ 1.栈的种类@ 1.1 使用满减栈@ 2.寄存器的使用@ 2.1 R15用作程序计数器,不能作其他用途 @ 2.2 R14用作链接寄存器,不能作其他用途@ 2.3 R13用作栈指针,不能作其他用途@ 2.4 当函数的参数不多于4个时使用R0-R3传递,当函数的参数多于4个时,多出的部分用栈传递@ 2.5 函数的返回值使用R0传递@ 2.6 其它寄存器主要用于存储局部变量
总结,参数尽量小于3,放在寄存器中效率高一点。