汇编与C混合编程
-汇编指令中调用C语言
.global _start
_start:
mov r0,#5
mov r1,#3
bl add
stop:
b stop
int add(int a,int b)
{
int c = a + b;
return c;
}
无优化情况:(反汇编之后,发现多了很多很多指令,运行之后结果是错误的)
无优化的情况下,在汇编中调用C语言代码,需要指定SP寄存器的值
.global _start
_start:
mov r0,#5
mov r1,#3
ldr sp,=0x2000fff0
bl add
stop:
b stop
-C语言内嵌汇编指令
在C语言中是无法操作寄存器,如果想操作寄存器,就可以在C语言中嵌套汇编指令
格式:
asm(
"指令1\n"
"指令2\n"
......
:输出列表
:输入列表
:修改列表(通用的寄存器)
);
指令:ARM汇编指令
输出列表:将内嵌汇编中的寄存器值输出到C变量
输入列表:将C变量输入到内嵌汇编中使用的寄存器
修改列表:内嵌汇编中修改的寄存器
实例:
int operate(int num1,int num2)
{
int result = 0;//result = num1*num2;
asm(
"mul r0,%1,%2\n"
"mov %0,r0"
:"=r"(result)
:"r"(num1),"r"(num2)
:"r0"
);
return result;
}
注意:
C语言的引用,从输出列表到输入列表开始编号;第一个C变量%0,第二个C变量%1...
gcc优化与volatile关键字
-gcc优化
gcc编译器常用的优化级别有三个:
1.O1(一级优化)
2.O2(speed)/Os(size)(二级优化)
3.O3(三级优化)
优化的思想:
如果我们在前面已经将这个变量所对应的内存数据读到寄存器中,而当我们再次需要读这个变量所对应内存的数据的时候,编译器认为前面我们已经在寄存器中,存放过值了,为了提高效率,它直接会使用上一次寄存器中的值,而不重新从内存中读值
优化的问题:
如果内存中的值已经被其他执行单元(中断处理函数或其他线程)做了更改,而优化后的代码每次存寄存器读值,就会带来寄存器中的值和内存中的值不一致的问题
-volatile关键字
volatile(译:易改变的)修饰一个变量,防止编译器优化(本质),告诉编译器每次在使用这个变量的时候,必须从变量所在的内存中重新读值
(当变量涉及被多个执行单元修改,则应该使用volatile修饰)