簡體   English   中英

AVR中的內聯匯編

[英]inline assembly in avr

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內聯匯編教程。 但是我並沒有得到很多。 有人可以幫我嗎?

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

在GCC手冊中記錄了一個約束“ m”,但它並不總是適用於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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM