C语言嵌入式汇编接口参数的两种表法方法
转载自我的另一个blog的文章:
https://blog.csdn.net/dbitc/article/details/111271739
C语言嵌入式汇编,如下形式
asm volatile("InSTructiON List" : Output : Input : Clobber/Modify);
asm是关键字,必选项
volatile 是可选的,加了,GCC 就不会优化这句。
汇编指令间必须被双引号括起来;
汇编指令间必须使用";"、"/n"或"/n/t"分开分开;
()内的是可选的,如asm volatile("")是可以的,只是无意义
仅省动其中一项,分号需要加上: 如这个省了输入和输出的,asm volatile ("sync" : : :"memory")
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)
);

浙公网安备 33010602011771号