avr中的内联汇编

时间:2016-06-02 18:12:15

标签: c assembly avr-gcc

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));
}

我有类似的东西。

!!!我想将寄存器r0 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内联汇编教程。但我不是很了解。 有谁可以帮助我?

2 个答案:

答案 0 :(得分:0)

<!DOCTYPE html> <html> <head> <script data-require="jquery@*" data-semver="2.2.0" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script> <script data-require="d3@*" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> <link rel="stylesheet" href="style.css" /> </head> <body> <form> <label><input type="radio" name="dataset" value="apples" checked> Apples</label> <label><input type="radio" name="dataset" value="oranges"> Oranges</label> </form> <script src="script.js"></script> </body> </html>毫无意义,应该是一个约束。尝试将堆栈指针保存到数组中也没有意义。使用该数组的地址加载堆栈指针可能是有意义的,但这不是"label"

无论如何,要获得作为堆栈指针的save_context的值,您可以执行以下操作:

SPL

(有一个asm volatile("in %0, %1": "=r" (*this_stack) : "I" (_SFR_IO_ADDR(SPL))); 约束,但至少我的gcc版本不喜欢它。)

要获得真正的寄存器,例如q,您可以这样做:

r26

答案 1 :(得分:0)

有一个约束“ m”,documented in the GCC manual,但它并不总是适用于AVR。这是一个如何从sanguino/bootloaders/atmega644p/ATmegaBOOT

开始工作的示例
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"