assembly avr中的内联汇编

0lvr5msh  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(257)
void save_context(uint8_t index) {
    context *this_context = contextArray + index;
    uint8_t *this_stack = this_context->stack;

    asm volatile("st %0 r0":  "r"(this_stack));
}

我有这样的东西。
!!!我想将寄存器r 0 r1 r2...存储到我的stack[]数组。
我正在编程的是上下文切换。上下文具有如下结构:

typedef struct context_t {
   uint8_t stack[THREAD_STACK_SIZE];
   void *pstack;
   struct context_t *next;
}context;

我的问题是我无法将c变量this_stack传递给内联汇编。我的目标是将所有的寄存器、堆栈指针和SREG存储在我的堆栈上。
编译后,它给出错误:说明资源路径位置类型

`,' required    5_multitasking      line 754, external location: C:\Users\Jiadong\AppData\Local\Temp\ccDo7xn3.s C/C++ Problem

我查了avr内联汇编教程。但是我没有得到很多。有人能帮助我吗?

cdmah0mi

cdmah0mi1#

asm volatile ("st %0 r0": "r"(this_stack));
这一行有几个问题:% print-modifier错误,操作数之间缺少,,约束不正确,缺少副作用说明。
内存访问应该使用间接寻址,因此一种方法是使用间接+位移和“B”寄存器Y或Z:

asm volatile ("std %a1+0, r0" "\n\t"
                  "std %a1+1, r1" "\n\t"
                  "..."
                  : "+m" (this_context->stack)
                  : "b" (this_stack));

注意print modifier %a,它将R30打印为Z而不是r30。操作数0只是用来表示this_context->stack正在被更改,如果你不想让"memory"完全内存乱码的话。此外,操作数1不需要中间变量,因为它没有被更改:您也可以对操作数1使用"b" (this_context->stack)
或者,可以使用“e“扩展(指针)寄存器X、Y或Z上的后递增寻址:

asm volatile ("st %a1+, r0" "\n\t"
                  "st %a1+, r1" "\n\t"
                  "..."
                  : "=m" (this_context->stack), "+e" (this_stack));
bvk5enib

bvk5enib2#

"label"没有意义,这应该是一个约束。试图将堆栈指针保存到一个数组中也没有意义。用该数组的地址加载堆栈指针可能有意义,但那不是save_context
无论如何,要获得SPL的值,也就是堆栈指针,可以执行以下操作:

asm volatile("in %0, %1": "=r" (*this_stack) : "I" (_SFR_IO_ADDR(SPL)));

(有一个q约束,但至少我的gcc版本不喜欢它。)
要获取真寄存器,例如r26,可以执行以下操作:

register uint8_t r26_value __asm__("r26");
asm volatile("": "=r" (r26_value));
a0x5cqrl

a0x5cqrl3#

这里有一个约束,“m”,documented in the GCC manual,但它并不总是在AVR上工作。

asm volatile("...
    ...
    "sts    %0,r16      \n\t"
    ...
    : "=m" (SPMCSR) : ... );

我发现“m”是脆弱的。如果一个函数在C代码中使用了一个变量,在内联汇编之外,编译器可能会选择把它放在Z寄存器中,并且它也会试图在汇编中使用Z。这会导致汇编错误,当与sts指令一起使用时。查看C编译器的汇编输出是调试这类问题的最好方法。
如果不使用“m”约束,您可以直接将所需的文字地址放入汇编代码中。例如,请参见pins_teensy. c,其中timer_0_fract_count不包含在:

asm volatile(
    ...
    "sts    timer0_fract_count, r24"    "\n\t"

相关问题