首先内嵌汇编的形式是
asm
(
“要执行的语句;”
:输出参数1,输入参数2,输入参数3
:输入参数4,输出参数5,输出参数6
:被改变的寄存器1,被改变的寄存器2
)
3个分号将四块参数分割开来
一般需要将变量输入给 汇编函数。然后从汇编输出结果出来。
第一部分 要执行的语句。
最好是每行都用分号结尾。再用引号括起来
asm
(
" mov r1,r2 ; "
"ldr r2,=0x3344;"
)
当需要有输入变量的时候。用%x来站位。x=0-9。随后根据是输出参数还是输入参数来 放到对应的位置。
假设要实现的是 a+b=c
int main()
{
asm
(
"mov r0,%2;"
"mov r1,%1;"
"add r1,r1,r0;"
"mov %0,r1"
:"=r"(c)
:"r"(a),"r"(b)
:"r0","r1"
);
}
这里用了三个占位符
%2 %0 %1 分别对应 "=r"(c) "r"(a) "r"(b) 这个对应是按照顺序来的。从%0-%9对应从输出列表参数->输入列表参数
这里的c a b分别用括号括起来。前面还有前缀修饰。 (c)的修饰是“=r” a和b的修饰的“r”
还有其他不同的修饰符。如下
r 通用寄存器 r0-r15
m 有效的内存地址
I 立即数
X 操作符只能作为输出
= 操作符只写
+ 可读也可写
& 只能作为输出
没有前缀 说明是只读的
最后的 :"r0","r1"
说明有改变了寄存器。r0 r1 这个可能是链接的时候,这些寄存器会保护起来。执行完毕后再恢复把。
基本的就是这样。后续随便补充一个例子
#include "stdio.h"
int main()
{
int v1=1,v2=2,v3=3;
int v4=0,v5=0,v6=0;
asm
(
"STMFD sp!,{%3,%4,%5};"
"pop {%0};"
"pop {%1};"
"pop {%2};"
/*"LDMFD sp!,{%0,%1,%2};"*/
:"=r"(v4),"=r"(v5),"=r"(v6)
:"r"(v1),"r"(v2),"r"(v3)
);
printf("test %d %d %d \n",v4,v5,v6);
return 1;
}
输出的结果是 3 2 1 说明STMFD是从左到右 push。而LDMFD同样也是从左到右的
其中三个pop和 "LDMFD sp!,{%0,%1,%2};“是等价的
有时候编译器会执行优化。为了不优化掉。可以使用
__asm__ __volatile__("mov r0,r0;"); 主要是__volatile__关键字