文章目录
伪操作与混合编程
1伪操作
伪操作:不会生成代码,只是在编译阶段告诉编译器怎么编译
1.1举例
GNU伪操作一般都与‘.’开头
.global 将一个符号声明为全局符号
.global symbol @将一个symbol 声明为全局
.local 将符号声明成局部符号
.local symbol @将一个symbol 声明为局部
.equ 相当于C语言中的宏
.equ DATA ,0xFF
MOV R1,#DATA
.macro … .endm 对汇编指令进行封装(相当于C语言中的函数)
.macro FUNC
MOV R1,#1
MOV R2,#2
.endm
FUNC@调用FUNC
.if … .endif 条件编译
.if 0
MOV R1,#1
MOV R2,#2
.endif
.rept … .endr 重复代码
.rept 3@生成3遍下面的代码
MOV R1,#1
MOV R1,#2
.endr
.word 在当前地址申请一个字节的空间并且初始化
MOV R1,#1
.word 0xFFFFFFFF
MOV R1,#2
.align 对齐
.byte 在当前地址申请一个位的空间并且初始化
MOV R1,#1
.byte 0xFFFFFFFF
.align 2 @2的2次方对齐 指令储存地址必须是四的整数倍,但是前面被占了一位所以要对齐
MOV R1,#2
.space 在当前位置申请任意一个字节
.text 表示接下来位代码段
.end 表示代码结束
.arm 表示是arm代码
.thumb 表示是thumb 代码
注意:不同编译器的伪操作是不同的。
2 C和汇编混合编程
原则:在那种语言环境下符合哪种语言的语法规则
1 在汇编中将c语言中的函数当作标号来处理
2 在C语言中将汇编语言的标号当作函数来处理
2.1 格式
2.2.1 汇编语言调用C语言
.s文件
@ 汇编
.text @表示为代码段
.global _start @将_strat定义为全局符号
_start: @ 汇编入口
MOV R1,#1
MOV R2,#2
BL func_c
MOV R3,#3
stop:
B stop
.end
.c文件
void func_c(void)
{
int a=0;
a++;
a--;
}
2.2.2 C语言调用汇编语言
.s文件
@ 汇编
.text @表示为代码段
.global _start @将_strat定义为全局符号
_start: @ 汇编入口
MOV R1,#1
MOV R2,#2
BL func_c
MOV R3,#3
.global FUNC_ASM@声明位全局
FUNC_ASM:
MOV R4,#4
MOV R5,#5
stop:
B stop
.end @汇编结束
.c 文件
void func_c(void)
{
int a=0;
a++;
a--;
FUNC_ASM();//记得括号要加
}
2.2.3 C内联汇编
void func_c(void)
{
int a=0;
a++;
a--;
asm
(
"MOV R6,#6\n"
"MOV R7,#7\n"
);
FUNC_ASM();
}
3 ATPCS协议
规定不同编译器在编译的时候做到标准化。
3.1协议的主要内容
1栈种类
使用满减栈。
2 寄存器的使用
1 R15 程序计数器
只能用于储存程序的指针,不能用做其他用途
2 R14 链接寄存器
只能用于存储返回地址,不能用于其他用途
3 R13 栈指针
只能用于储存栈指针,不能用作其他用途
4 R0-R3
当函数的参数少于4个时使用R0-R3,多出的部分用栈传递。
5 函数返回值放在R0
6 其余寄存器主要用于储存局部变量