伪操作
@ 3.伪操作:不会生成代码,只是在编译之前告诉编译器怎么编译
@ GNU的伪操作一般都以‘.’开头
@ .global symbol
@ 将symbol声明成全局符号
@ .local symbol
@ 将symbol声明成局部符号
@ .equ DATA, 0xFF
@ MOV R1, #DATA
@ .macro FUNC
@ MOV R1, #1
@ MOV R2, #2
@ .endm
@ FUNC
@ .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
@ 定义一个数据段
@ .space N, VALUE
@ 在当前地址申请N个字节的空间并将其初始化为VALUE
@ MOV R1, #1
@ .space 12, 0x12
@ MOV R2, #2
@ 不同的编译器伪操作的语法不同
c和汇编的混合编程
@ C和汇编的混合编程
@ C和汇编的混合编程原则:在哪种语言环境下符合哪种语言的语法规则
@ 1. 在汇编中将C中的函数当做标号处理
@ 2. 在C中将汇编中的标号当做函数处理
@ 3. 在C中内联的汇编当做C的语句来处理
@ 1. 方式一:汇编语言调用(跳转)C语言
@ MOV R1, #1
@ MOV R2, #2
@ BL func_c
@ MOV R3, #3
@ 2. 方式二:C语言调用(跳转)汇编语言
@ .global FUNC_ASM
@ FUNC_ASM:
@ MOV R4, #4
@ MOV R5, #5
@ 3. C内联(内嵌)汇编
main.c
void func_c(void)
{
int a;
a ++;
//C内联(内嵌)汇编
asm
(
"MOV R6, #6\n"
"MOV R7, #7\n"
);
//C语言调用(跳转)汇编语言
FUNC_ASM();
a --;
}
ATPCS协议
@ ATPCS协议(ARM-THUMB Procedure Call Standard)
@ 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 其它寄存器主要用于存储局部变量
例子:main.c
int a=1,b=1,c=1,d=1,e=1,f=1,g;
int func(int a,int b,int c,int d,int e,int f)
{
return a+b+c+d+e+f;
}
int main(void)
{
g = func(a,b,c,d,e,f);
return 0;
}