1 引入
内联汇编即在C函数中使用汇编去实现某些功能。
为什么需要在C代码中引入汇编?
- C语言在大多数的时候效率都很高,但在某些情况下直接使用汇编效率会更加高效
- 部分功能通过C语言很难实现,这部分代码就需要使用汇编去实现(实现某些功能)
在C文件中使用汇编存在两种方法
- 在
.s
文件去实现某个功能函数,在C文件中去调用(缺点:需要另外建一个文件) - 在C文件中直接使用汇编代码去实现
1.1 示例
1.1.1 C语言实现add
通过C语言实现add
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int main(int argc, char **argv)
{
int a = 1;
int b = 2;
int sum;
sum = add(a, b);
printf("sum:%d\n", sum);
return 0;
}
arm-linux-objdump -D test > test.dis
00010410 <add>:
10410: e52db004 push {fp} ; (str fp, [sp, #-4]!)
10414: e28db000 add fp, sp, #0
10418: e24dd00c sub sp, sp, #12
1041c: e50b0008 str r0, [fp, #-8]
10420: e50b100c str r1, [fp, #-12]
10424: e51b2008 ldr r2, [fp, #-8]
10428: e51b300c ldr r3, [fp, #-12]
1042c: e0823003 add r3, r2, r3 //这句实现add
10430: e1a00003 mov r0, r3
10434: e28bd000 add sp, fp, #0
10438: e49db004 pop {fp} ; (ldr fp, [sp], #4)
1043c: e12fff1e bx lr
通过反汇编文件中add信息可以看出add函数有很多操作入栈,出栈的操作所以效率并不是极致的
2 内联汇编语法
-
asm
一般写作
__asm__
,表示这是一段内联汇编 -
asm-qualifiers
存在三个值:volatile(常用)、inline、goto
-
AssmblerTemplate
汇编指令。用
""
双引号包含,用\n
分开"mov %0, %1\n"
-
OutputOperands
输出结果保存在这里
格式:
[ [asmSymbolicName] ] constraint (cvariablename)
-
asmSymbolicName
可以不写
-
constraint
表示约束
常用值
constraint 描述 m memory operand,表示传入的地址,需要CPU支持的地址 r register operand,使用这个寄存器保存 i immediate integer operand,传入一个立即数 数据修饰
constraint Modifier Characters 描述 = 内联汇编会去修改;即写 + 即能读能写 & earlyclobber;gcc尚未使用完全部的输入操作数时,就产生了某些输出操作 关于
earlyclobber(&)
在内联汇编中没有指定使用的具体寄存器。这会导致某个寄存器会被反复使用,前面使用过此寄存器保存的值,会因为后面再次使用而被修改
此时使用
earlyclobber(&)
则是告诉编译器对于某个操作它所使用的寄存器不能跟其他操作数共用寄存器示例
"=&r"(sum)
即
%0
的操作不能和其他%1
、%2
等共用寄存器 -
cvariablename
变量名;为输出指定一个C左值
-
示例.
"=r" (sum)
汇编中会将
r
寄存器中的值写入sum
变量
-
-
InputOperands
格式(基本与OutputOperands相同):
[ [asmSymbolicName] ] constraint (cexpression)
-
cexpression
这里是表达式
-
示例
"r"(a), "r"(b)
将
a
放入某个寄存器r
,将b
放入某个寄存器r
;可以使用%0
,%1
调用
-
-
Clobbers
声明汇编中会修改的事件(寄存器,内存)
Clobbers 描述 cc 表示汇编代码会修改寄存器 memory 表示汇编代码除开InputOperands和OutputOperands外还会操作内存
OutputOperands和InputOperands引用
从:
后开始依次为%0 %1 %2 ...
3 内联汇编实现add
int add(int a, int b)
{
int sum;
__asm__ volatile (
"add %0, %1, %2"
:"=&r"(sum)
:"r"(a), "r"(b)
:"cc"
);
return sum;
}
没使用&
1042c: e0833002 add r3, r3, r2
使用&
1042c: e0823001 add r3, r2, r1
标签:fp,汇编,16,int,sum,互斥,add,寄存器,内联
From: https://www.cnblogs.com/burnk/p/17280723.html