GCC中内嵌arm汇编


首先内嵌汇编的形式是

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__关键字













评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值