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

标签 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

最佳答案

那么是这样的吗?

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

关于c - XC16 编译器 - 为 BTSTS(间接内存寻址)创建内存操作数的内联汇编约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54256472/

相关文章:

c++ - 简单的 g++ 内联汇编程序出错

c - 如何在 GCC x86 内联汇编中使用地址常量

c - 错误 : invalid type argument of unary ‘*’ (have ‘long int’ )

c - 如何通过同一个管道向多个进程发送消息? (C语言)

c - 同时编译.pc和.c时makefile无故退出。很奇怪

c - 如何使用此 malloc 语句分配内存?

c - 关于重新分配的问题

c - 2d 链表内存未结转

linux - Linux RSS 不等于 java Xx + MaxMetaspaceSize 吗?

c++ - 对于 x86 汇编和优化代码中的循环?