在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 建立一個(gè)AVR的RTOS(3)—GCC中對(duì)寄存器的分配與使用

            建立一個(gè)AVR的RTOS(3)—GCC中對(duì)寄存器的分配與使用

            作者: 時(shí)間:2016-12-03 來源:網(wǎng)絡(luò) 收藏
            第三篇:GCC中對(duì)寄存器的分配與使用

            在很多用于AVRRTOS中,都會(huì)有任務(wù)調(diào)度時(shí),插入以下的語句:

            本文引用地址:http://www.biyoush.com/article/201612/325274.htm

            入棧:

            __asm__ __volatile__("PUSH R0 nt");

            __asm__ __volatile__("PUSH R1 nt");

            ......

            __asm__ __volatile__("PUSH R31 nt");

            出棧

            __asm__ __volatile__("POP R31 nt");

            ......

            __asm__ __volatile__("POP R1 nt");

            __asm__ __volatile__("POP R0 nt");

            通常大家都會(huì)認(rèn)為,在任務(wù)調(diào)度開始時(shí),當(dāng)然要將所有的通用寄存器都保存,并且還應(yīng)該保存程序狀態(tài)寄存器SREG。然后再根據(jù)相反的次序,將新任務(wù)的寄存器的內(nèi)容恢復(fù)。

            但是,事實(shí)真的是這樣嗎?如果大家看過陳明計(jì)先生寫的small rots51,就會(huì)發(fā)現(xiàn),它所保存的通用寄存器不過是4組通用寄存器中的1組。

            在Win AVR中的幫助文件avr-libc Manual中的Related Pages中的Frequently Asked Questions,其實(shí)有一個(gè)問題是"What registers are used by the C compiler?"回答了編譯器所需要占用的寄存器。一般情況下,編譯器會(huì)先用到以下寄存器

            1 Call-used registers (r18-r27, r30-r31):調(diào)用函數(shù)時(shí)作為參數(shù)傳遞,也就是用得最多的寄存器。

            2 Call-saved registers (r2-r17, r28-r29):調(diào)用函數(shù)時(shí)作為結(jié)果傳遞,當(dāng)中的r28和r29可能會(huì)被作為指向堆棧上的變量的指針。

            3 Fixed registers (r0, r1):固定作用。r0用于存放臨時(shí)數(shù)據(jù),r1用于存放0。

            還有另一個(gè)問題是"How to permanently bind a variable to a register?",是將變量綁定到通用寄存器的方法。而且我發(fā)現(xiàn),如果將某個(gè)寄存器定義為變量,編譯器就會(huì)不將該寄存器分配作其它用途。這對(duì)RTOS是很重要的。

            在"Inline Asm"中的"C Names Used in Assembler Code"明確表示,如果將太多的通用寄存器定義為變量,剛在編譯的過程中,被定義的變量依然可能被編譯器占用。

            大家可以比較以下兩個(gè)例子,看看編譯器產(chǎn)生的代碼:(在*.lst文件中)

            第一個(gè)例子:沒有定義通用寄存器為變量

            #include

            unsigned char add(unsigned char b,unsigned char c,unsigned char d)

            {

            return b+c*d;

            }

            int main(void)

            {

            unsigned char a=0;

            while(1)

            {

            a++;

            PORTB=add(a,a,a);

            }

            }

            在本例中,"add(a,a,a);"被編譯如下:

            mov r20,r28

            mov r22,r28

            mov r24,r28

            rcall add

            第二個(gè)例子:定義通用寄存器為變量

            #include

            unsigned char add(unsigned char b,unsigned char c,unsigned char d)

            {

            return b+c*d;

            }

            register unsigned char a asm("r20"); //將r20定義為變量a

            int main(void)

            {

            while(1)

            {

            a++;

            PORTB=add(a,a,a);

            }

            }

            在本例中,"add(a,a,a);"被編譯如下:

            mov r22,r20

            mov r24,r20

            rcall add

            當(dāng)然,在上面兩個(gè)例子中,有部份代碼被編譯器優(yōu)化了。

            通過反復(fù)測(cè)試,發(fā)現(xiàn)編譯器一般使用如下寄存器:

            第1類寄存器,第2類寄存器的r28,r29,第3類寄存器

            如在中斷函數(shù)中有調(diào)用基它函數(shù),剛會(huì)在進(jìn)入中斷后,固定地將第1類寄存器和第3類寄存器入棧,在退出中斷又將它們出棧。



            關(guān)鍵詞: AVRRTOSGCC寄存

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉