XC16编译器-内​​联汇编约束为BTSTS(间接内存寻址)创建内存操作数

时间:2019-01-18 14:57:43

标签: c memory inline-assembly xc16

我要创建的是一种用于调用BTSTS指令的c高级方法。

到目前为止我尝试过的事情:

volatile unsigned int a = 1;
asm volatile(
    "btsts %0, #2\n"
    : "+d" (b)
    : 
    : "cc"
);

上面产生以下程序集输出:

mov #1,w0
mov w0,[w14]
mov [w14],w0
mov w0,w1

btsts   w1, #2

mov w1,w0
mov w0,[w14]

但这不是我想要的。该位应直接在内存中设置,以使指令具有原子性:

btsts   [w0], #2

完成这项工作的正确方法是什么?

最近的方法是:

此处“ a”是全局变量而不是局部变量

asm volatile(
    "btsts [%0], #2\n"
    :
    : "d" (&a)
    : "cc"
);

这次生成了以下程序集输出:

mov _a,w0
mov w0,w1
btsts [w1], #2

这好一点,但是我不想在它周围明确指定大括号[%0]。 难道编译器/汇编器不会知道是否需要间接内存寻址吗?

编辑:我又尝试了一件事。尽管我尝试了文档中没有提到“ m”约束的事实

volatile unsigned int r = 0;
void test(volatile unsigned int* t) {
       asm (
       "btsts %0, #2\n"
       : "+m" (t)
   );
}

以上将产生类似

mov #_r,w0 
...
mov w0,[w14]
btsts [w14], #2

这也不正确,不会更改r。也许没有提及“ m”个约束,因为它是越野车?

顺便说一句。正确的代码是

btsts [w0], #2

或类似的

mov w0,[w14]
mov [w14],w1
btsts [w1], #2

1 个答案:

答案 0 :(得分:0)

那是什么?

unsigned short a __at((0x100)) = 1;

int main()
{
   asm (
       "btsts %0, #2\n"
       : "+m" (a)
   );
   return a;
}

使用xc16-gcc -mcci -O1 -mcpu = 30F4011 -S m.c构建

_main:
        .set ___PA___,0
        btsts   _a, #2

        mov     _a,w0
        return