C语言嵌入式汇编

17 篇文章 0 订阅
3 篇文章 0 订阅

    C语言嵌入式汇编,如下形式

asm volatile("InSTructiON List" : Output : Input : Clobber/Modify);
  1. asm是关键字,必选项
  2. volatile 是可选的,加了,GCC 就不会优化这句。
  3. 汇编指令间必须被双引号括起来;
  4. 汇编指令间必须使用";"、"/n"或"/n/t"分开分开;
  5. ()内的是可选的,如asm volatile("")是可以的,只是无意义
  6. 仅省动其中一项,分号需要加上: 如这个省了输入和输出的,asm volatile ("sync" : : :"memory")
  7. Clobber/Modify表示特定的关键字,让汇编做相应的动作

输入和输出及最后的前缀说明:

  • “=”: 表示只写,常用于输出参数。
  • “+": 表示可读可写
  • "m"、"v"和"o":内存操作单元,V:寻址方式不是偏移量类型;  o:寻址方式是偏移量类型
  • "r": 寄存器单元
  • "i"和"h" :常数
  • "E"和"F":浮点数
  •  "a": 输入变量放入eax
  • "p": 合法的内存指针
  • "memory": 表示通知有内存变动
  • "&": 该输出操作数不能使用和输入操作数相同的寄存器
  • "X": 表示任何类型
  • "*: 表示如果选用寄存器,则其后的字母被忽略
  • # 部分行注释,从该字符到其后的逗号之间所有字母被忽略

 示例1:接口参数汇编中用0% ,1%这种来表示

占位符引用C语言变量,操作数占位符最多10 个,名称如下:%0,%1,...,%9。指令中使用占位符表示的操作数,总被视为long型(4个字节),在%和序号之间插入一个字母,"b"代表低字节,"h"代表高字节,例如:%h0

unsigned val;
asm volatile("lhbrx %0,0,%1" 
               : "=r" (val) 
               : "r" (addr), "m" (*addr));
return val;

0% 表示第一个参数, 1%这种数字表示第二个参数,依次类推

0%对应输出参数val, 1%对应输入参数:addr, 需要数位置,且容易搞混。

示例2:接口参数汇编中用%[xx]表示,这种更形像,也不用数位置。

        uint32_t csr_addrh = csr_addr>>32;                              \
        uint32_t csr_addrl = csr_addr;                                  \
        uint32_t tmp1;                                                  \
        uint32_t tmp2;                                                  \
                                                                        \
        asm volatile (                                                  \
            ".set push\n"                                             \
            ".set mips64\n"                                             \
            "dsll   %[tmp1], %[csrh], 32\n"                             \
            "dsll   %[tmp2], %[csrl], 32\n"                             \
            "dsrl   %[tmp2], %[tmp2], 32\n"                             \
            "or     %[tmp1], %[tmp1], %[tmp2]\n"                        \
            "sd     %[val], 0(%[tmp1])\n"                               \
            ".set pop\n"                                                \
            : [tmp1] "=&r" (tmp1), [tmp2] "=&r" (tmp2)                  \
            : [val] "r" (val), [csrh] "r" (csr_addrh),                  \
              [csrl] "r" (csr_addrl)                                    \
        );                                                              

GCC上的相关说明:Extended Asm (Using the GNU Compiler Collection (GCC))

伪指令:

.set noreorder/.set reorder : 
     不让/让 汇编重排优化指令;
     默认是reorder, reorder下不能用nop;
     noreorder,下需要自行增加nop来调时序
.set push : 存当前状态
.set pop : 恢复当前状态
.set at/noat :让/不让 汇编使用 $at

汇编中的1b, 1f

#后在的字母:b表示backward, f表示:forward
# b 2f #表示向前跳转到标记2
# b 2b #表示向后跳转到标记2

#实例:
asm volatile(
        "   b       2f                          \n"
        "1: lwzx    %0, 0, %1                   \n"
        "   cmpwi   0, %0, 0                    \n"
        "   bne+    1b                          \n"
        "2: lwarx   %0, 0, %1                   \n"
        :"=&r" (a0)
        : "r"(a1), "r"(a2)
        : "cr0", "memory");

已在如下URL, 我的cnblog上转载:

C语言嵌入式汇编接口参数的两种表法方法 - potac - 博客园

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值