内联汇编即在C中直接运用汇编句子进行编程,使程序能够在C程序中完结C言语不能完结的一些作业,例如,在下面几种状况中有必要运用内联汇编或嵌入型汇编
程序中运用饱满算术运算(Saturating ArithmeTIc)
程序需要对协处理器进行操作
在C程序中完结对程序状况寄存器的操作
__asm__ __volaTIle__(“asm code”:output:input:changed registers);
Note:
运用__asm__和__volaTIle__表明编译器将不查看后边的内容,而是直接交给汇编器。
假如期望变压器你优化,__volaTIle__能够不加
没有asm code也不能省掉””
没有前面的和中心的部分,不能够相应的省掉:
没有changed 部分,有必要相应的省掉:
最终的;不能省掉,关于C言语来说这是一条句子
汇编代码有必要放在一个字符串内,且字符串中心不能直接按回车换行,能够写成多个字符串,留意中心不能有任何符号,这样就会将两个字符串合并为一个指令之间有必要要换行,还能够运用\t使指令在汇编中坚持规整
asm code
“mov r0, r0\n\t””mov r1,r1\n\t””mov r2,r2”
output(asm->C)
:”constraint” (variable)
“constraint”用于界说variable的寄存方位:
r表明运用任何可用的寄存器
m表明运用变量的内存地址
+可读可写
=只写
&表明该输出操作数不能运用输入部分运用过的寄存器,只能用”+&”或”=&”的方法运用
input(C->asm)
:”constraint” (variable/immediate)
“constraint”用于界说variable的寄存方位:
r表明运用任何可用的寄存器(当即数和变量都能够)
m表明运用变量的内存地址
i表明运用当即数
比如
int a=100,b=200;int result;__asm__ __volatile__( “mov %0,%3\n\t” //%0是一个占位符,表明result,之后的类推 “ldr r0,%1\n\t” “ldr r1,%2\n\t” “str r0,%2\n\t” “str %1,%1\n\t” :”=r”(result),”+m”(a),”+m”(b) :”i”(123));
ATPCS
子程序间经过寄存器R0~R3来传递参数,假如参数多于四个,则多出的部分用仓库传递,被调用的子程序在回来前无须康复寄存器R0~R3的内容
在子程序中,运用寄存器R4~R11来保存局部变量,假如在子程序中运用到了R4~R11中的某些寄存器,子程序进入时有必要保存这些寄存器的值,在回来前有必要康复这些寄存器的值;关于子程序中没有用到的寄存器则不用进行这些操作,在Thumb程序中,一般只能运用寄存器R4~R7来保存局部变量
R12用作子程序间scrtach寄存器(用于保存SP,在函数回来时运用该寄存器出栈),记作ip
R13用作数据栈指针,记作sp
R14用作衔接寄存器,记作lr
R15记作程序寄存器,记作pc
彼此调用
C和汇编彼此调用要特别留意恪守相应的ATPCS规矩
C调用汇编
//.c#include extern void strcopy(char* des, const char* src);int main(){ const char* srcstr = “src string”; char desstr[]=”des string”; strcopy(desstr, srcstr); return 0;}
;.asm.global strcopystrcopy: ;R0指向意图字符串 ;R1指向源字符串 LDRB R2, [R1], #1 ;加载字节并更新源字符串指针地址 STRB R2, [R0], #1 ;存储时节并更新意图字符串指针地址 CMP R2, #0 ;判别是否为字符串结束 BNE strcopy ;假如不是,程序跳转到strcopy持续循环 MOV pc, ir ;程序回来
汇编调用C
//.cint fcn(int a, int b , int c, int d, int e){ return a+b+c+d+e;}
;.asm;假定程序进入f时,R0中的值为i;int f(int i){return fcn(i, 2*i, 3*i, 4*i, 5*i);}.text.global _start_start: STR lr, [sp, #-4]! ;保存回来地址lr ADD R1, R0, R0 ;核算2*i(第2个参数) ADD R2, R1, R0 ;核算3*i(第3个参数) ADD R3, R1, R2 ;核算5*i STR R3, [SP, #-4]! ;第5个参数经过仓库传递 ADD R3, R1, R1 ;核算4*i(第4个参数) BL fcn ;调用C程序 ADD sp, sp, #4 ;从仓库中删去第五个参数 .end