我必须实现set_bit函数,它应该是一个原子操作。我在linux源代码中找到了这方面的汇编代码。(我正在使用sparc),并希望将其更改为可以在C程序中使用的函数。
static void set_bit(unsigned int nr, unsigned int *addr)
{
// *vec |= 1<<bit; <== original non-atomic C code
//set_bit: /* %o0=nr, %o1=addr */ <== nr is in %o0, addr in %o1 by sparc rule
__asm__ __volatile__ (
"srlx %o0, 6, %g1"
"mov 1, %o2"
"sllx %g1, 3, %g3"
"and %o0, 63, %g2"
"sllx %o2, %g2, %o2"
"add %o1, %g3, %o1"
"1: ldx [%o1], %g7"
"or %g7, %o2, %g1"
"casx [%o1], %g7, %g1"
"cmp %g7, %g1"
"bne,pn %xcc, 2f"
"nop"
"retl"
"nop"
: "=m"(addr) // output
: "m"(nr) // input
: );这是正确的吗?我是否在最后一行列出了所有的clobberd寄存器?
我看到下面的错误消息..
../../../../../rtems-4.10.99-src/c/src/libchip/sdmmc/ald-sd-card.c:135:1: error: invalid 'asm': invalid operand output code
__asm__ __volatile__ (
^
../../../../../rtems-4.10.99-src/c/src/libchip/sdmmc/ald-sd-card.c:135:1: error: invalid 'asm': invalid operand output code
../../../../../rtems-4.10.99-src/c/src/libchip/sdmmc/ald-sd-card.c:135:1: error: invalid 'asm': operand number out of range
^发布于 2015-09-05 22:14:55
我认为您应该在字符串中的每一行只编写一条指令(在每条指令的末尾添加\n\t )。
static void set_bit(unsigned int nr, unsigned int *addr)
{
// *vec |= 1<<bit; <== original non-atomic C code
//set_bit: /* %o0=nr, %o1=addr */ <== nr is in %o0, addr in %o1 by sparc rule
__asm__ __volatile__ (
"srlx %o0, 6, %g1\n\t"
"mov 1, %o2\n\t"
"sllx %g1, 3, %g3\n\t"
"and %o0, 63, %g2\n\t"
"sllx %o2, %g2, %o2\n\t"
"add %o1, %g3, %o1\n\t"
"1: ldx [%o1], %g7\n\t"
"or %g7, %o2, %g1\n\t"
"casx [%o1], %g7, %g1\n\t"
"cmp %g7, %g1\n\t"
"bne,pn %xcc, 2f\n\t"
"nop\n\t"
"retl\n\t"
"nop\n\t"
: "=m"(addr) // output
: "m"(nr) // input
: );
}发布于 2015-09-06 18:33:40
看起来你用的是GCC。
正如@MikeCAT所说,指令需要在单独的行上。
您需要将寄存器名称中的所有%加倍。%%将成为输出程序集中的%。
根据
规则,地址nr位于%o0,地址位于%o1
没有这样的规则,你可能会想到函数调用ABI,它不适用于内联汇编。如您所问,GCC期望将addr写入内存位置%0,而nr位于内存位置%1:
:“=m”(地址) //输出:"m"(nr) //输入
但是addr不是输出。*addr是一个输入/输出,或者addr是一个输入,并且"memory"必须在clobber列表中。对于nr来说,寄存器将是更好的位置
:"+m"(*addr) //输入输出:"r"(nr) //输入
你不应该把retl放在那里,因为它跳到了一个未定义的位置,控制流应该到达终点。
您必须列出所有更改的寄存器,要么作为输出,要么作为缓冲器。
如果这被认为是一个内存屏障,那么"memory"必须出现在拦截器列表中。
我建议您参考GCC Manual。
编辑:错过了一个指针引用。
https://stackoverflow.com/questions/32412746
复制相似问题