rk3288 内联汇编

一、内联汇编

在c语言中可以直接调用内联汇编,提高代码的运行效率,或者有时需要调用特殊的汇编指令。(比如ldrex/strex实现互斥访问),比如一些平台的特定指令在c中没有对应的操作等等,这些都需要内联汇编。

参考文章:
① GNU C扩展汇编
② ARM GCC 内嵌(inline)汇编手册
③ C内联汇编

  1. c语言实现的加法:
int add(int a, int b)
{
	return a+b;
}

反汇编后,

00010404 <add>:
   10404:   b480        push    {r7}
   10406:   b083        sub sp, #12
   10408:   af00        add r7, sp, #0
   1040a:   6078        str r0, [r7, #4]
   1040c:   6039        str r1, [r7, #0]
   1040e:   687a        ldr r2, [r7, #4]
   10410:   683b        ldr r3, [r7, #0]
   10412:   4413        add r3, r2				//实现加法的只有这一条,但是需要做入栈,出栈的操作
   10414:   4618        mov r0, r3
   10416:   370c        adds    r7, #12
   10418:   46bd        mov sp, r7
   1041a:   f85d 7b04   ldr.w   r7, [sp], #4
   1041e:   4770        bx  lr
  1. 使用汇编函数实现的加法:
.text            // 放在代码段
.global  add     // 实现全局函数add
.thumb           // 使用thumb指令, main.c默认使用thumb指令, 所以这里也使用thumb指令

add:
    add r0, r0, r1
    bx lr

根据ATPCS规则,main调用add,会把第一个参数存入r0,第二个r1,这样就没有入栈和出栈的操作了,比较高效。

其实还有另一种语法可以实现汇编,在c语言中调用内联汇编。

二、内联汇编语法

asm asm-qualifiers ( AssemblerTemplate 
                 : OutputOperands 
                 [ : InputOperands
                 [ : Clobbers ] ])

asm asm-qualifiers ( AssemblerTemplate 
                      : OutputOperands
                      : InputOperands
                      : Clobbers
                      : GotoLabels)
  • asm:也可以写作"__asm__",表示这是一段内联汇编
  • asm-qualifiers:有3个取值,volatile、inline、goto。其中volatile是告诉编译器不要随意优化这段代码。
  • AssemblerTemplate:汇编指令内容,用双引号包含起来,用\n来分开每一条指令
  • OutputOperands:输出操作数,输出的结果保存在哪里。
    [ [asmSymbolicName] ] constraint (cvariablename)
    • asmSymbolicName是符号名,随便取,也可以省略。
    • constraint表示约束
    • cvariablename:c语言的表两名

constraint表示约束,有如下常用的值

constraint描述
mmemory operand,表示要传入有效的地址,只要CPU能支持该地址,就可以传入
rregister operand,寄存器操作数,使用寄存器来保存这些操作数
iimediate integer operand,表示可以传入一个立即数

constraint前还可以加上一些修饰符,比如"=r"、"+r"、"=&r"

constraint Modifier Characters描述
=表示内联汇编会修改这个操作数,即:写
+这个操作数即被读,也被写
&它是一个earlyclobber操作数
  • InputOperands:输入操作数,内联汇编执行前,输入的数据保存在哪里
    [ [asmSymbolicName] ] constraint (cexpression)

    • asmSymbolicName是符号名,随便取,也可以省略。
    • constraint表示约束,跟OutputOperands类似。
    • cexpression:c语言的表两名
  • Clobbers:对于OutputOperands所涉及的寄存器、内存,肯定做了修改,必须声明会被修改的寄存器

常用的cc、memory意义如下

Clobbers描述
cc表示汇编代码会修改“flags register”
memory表示汇编代码中,除了InputOperands和OutputOperands中指定的之外,还会读写更多的内存

三、内联函数实现的加法

int add(int a, int b)
{
    int sum;
    __asm__ volatile (
        "add %0, %1, %2"				//把第1、2个操作数相加,放入第0个操作数,就是a+b放入sum
        :"=r"(sum)
        :"r"(a), "r"(b)
        :"cc"
    );
    return sum;
}
  • earlyclobber
    在OutpuOperands中经常有“&”符号,表示告诉编译器单独分配一个寄存器,不要和输入操作数用同一个寄存器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

习惯就好zz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值