亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

ARM嵌入式開發中的GCC內聯匯編簡介

系統 2021 0

ARM嵌入式開發中的GCC內聯匯編簡介

嵌入式開發交流群280352802,歡迎加入!

在針對ARM體系結構的編程中,一般很難直接使用C語言產生操作協處理器的相關代碼,因此使用匯編語言來實現就成為了唯一的選擇。但如果完全通過匯編代碼實現,又會過于復雜、難以調試。因此,C語言內嵌匯編的方式倒是一個不錯的選擇。然而,使用內聯匯編的一個主要問題是,內聯匯編的語法格式與使用的編譯器直接相關,也就是說,使用不同的C編譯器內聯匯編代碼時,它們的寫法是各不相同的。下面介紹在ARM體系結構下GCC的內聯匯編。 GCC內聯匯編的一般格式:

    asm(  


     代碼列表  
     : 輸出運算符列表  
     : 輸入運算符列表  
     : 被更改資源列表  
);
  

在C代碼中嵌入匯編需要使用asm關鍵字,在asm的修飾下,代碼列表、輸出運算符列表、輸入運算符列表和被更改的資源列表這4個部分被3個“:”分隔。下面,我們看一個例子:

    void test(void)
{  
    ……  
    asm(  
        "mov r1,#1\n"  
        :  
        :  
        :"r1"  
    );  
    ……  
} 
  

注:換行符和制表符的使用可以使得指令列表看起來變得美觀。你第一次看起來可能有點怪異,但是當C編譯器編譯C語句的是候,它就是按照上面(換行和制表)生成匯編的。

函數test中內嵌了一條匯編指令實現將立即數1賦值給寄存器R1的操作。由于沒有任何形式的輸出和輸入,因此輸出和輸入列表的位置上什么都沒有填寫。但是,在匯編代碼執行過程中R1寄存器會被修改,因此為了通知編譯器,在被更改資源列表中,需要寫上寄存器R1。

寄存器被修改這種現象發生的頻率還是比較高的。例如,在調用某段匯編程序之前,寄存器R1可能已經保存了某個重要數據,當匯編指令被調用之后,R1寄存器被賦予了新的值,原來的值就會被修改,所以,需要將會被修改的寄存器放入到被更改資源列表中,這樣編譯器會自動幫助我們解決這個問題。也可以說,出現在被更改資源列表中的資源會在調用匯編代碼一開始就首先保存起來,然后在匯編代碼結束時釋放出去。所以,上面的代碼與如下代碼從語義上來說是等價的。

    void test(void)
{  
    ……  
    asm(  
        "stmfd sp!,{r1}\n"
        "mov r1,#1\n"  
        "ldmfd sp!,{r1}\n"  
    );  
    ……  
}
  

這段代碼中的內聯匯編既無輸出又無輸入,也沒有資源被更改,只留下了匯編代碼的部分。由于程序在修改R1之前已經將寄存器R1的值壓入了堆棧,在使用完之后,又將R1的值從堆棧中彈出,所以,通過被更改資源列表來臨時保存R1的值就沒什么必要了。

在以上兩段代碼中,匯編指令都是獨立運行的。但更多的時候,C和內聯匯編之間會存在一種交互。C程序需要把某些值傳遞給內聯匯編運算,內聯匯編也會把運算結果輸出給C代碼。此時就可以通過將適當的值列在輸入運算符列表和輸出運算符列表中來實現這一要求。請看下面的例子:

    void test(void)
{  
    int tmp=5;  
    asm(  
        "mov r4,%0\n"  
        :  
        :"r"(tmp)  
        :"r4"  
    );  
} 
  

上面的代碼中有一條mov指令,該指令將%0賦值給R4。這里,符號%0代表出現在輸入運算符列表和輸出運算符列表中的第一個值。如果%1存在的話,那么它就代表出現在列表中的第二個值,依此類推。所以,在該段代碼中,%0代表的就是“r”(tmp)這個表達式的值了。
那么這個新的表達式又該怎樣解釋呢?原來,在“r”(tmp)這個表達式中,tmp代表的正是C語言向內聯匯編輸入的變量,操作符“r”則代表tmp的值會通過某一個寄存器來傳遞。在GCC4中與之相類似的操作符還包括“m”、“I”,等等,其含義見下表:


與輸入運算符列表的應用方法一致,當C語言需要利用內聯匯編輸出結果時,可以使用輸出運算符列表來實現,其格式應該是下面這樣的。

    void test(void)
{  
    int tmp;  
    asm(  
        "mov %0,#1\n"  
        :"=r"(tmp)  
        :  
    );  
} 
  

在上面的代碼中,原本應出現在輸入運算符列表中的運算符,現在出現在了輸出運算符列表中,同時變量tmp將會存儲內聯匯編的輸出結果。這里有一點可能已經引起大家的注意了,上面的代碼中操作符r的前面多了一個“=”。這個等號被稱為約束修飾符,其作用是對內聯匯編的操作符進行修飾。幾種修飾符的含義如下表所示:

當一個操作符沒有修飾符對其進行修飾時,代表這個操作符是只讀的。當我們需要將內聯匯編的結果輸出出來,那么至少要保證該操作符是可寫的。因此,“=”或者“+”也就必不可少了。

ARM嵌入式開發中的GCC內聯匯編簡介


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人在线短视频 | 欧美精品一区二区三区在线播放 | 国产高清视频在线免费观看 | 四虎影 | 日韩视频一区二区在线观看 | 在线免费观看中文字幕 | 真人毛片免费拍拍拍aa视频 | 毛片高清 | 99热这里只有精品国产免费 | 亚洲精品色播一区二区 | 狠狠色丁香婷婷综合久久来 | 女人牲交视频一级毛片 | 日日操夜夜摸 | 日韩色视频一区二区三区亚洲 | 深夜福利国产 | 亚欧洲精品bb | 热久久在线观看 | 四虎网址换成什么了2021 | 国产九九在线 | 欧日韩在线不卡视频 | 深夜福利影院 | 久久成| 水浒传删减剧情在线观看 | 欧美日韩免费做爰视频 | 欧美xxxxbbbb在线播放 | 成年午夜视频免费观看视频 | 精品成人一区二区 | 欧美 日韩 国产在线 | 亚洲欧美综合区自拍另类 | 亚洲国产美女精品久久久久 | 日韩a级黄色片 | 国产高清久久99 | 色偷偷亚洲精品一区 | 在线亚洲 欧美 日本专区 | 成人免费视频在线观看 | 欧美日韩一二三区免费视频观看 | 日本国产成人精品视频 | www.四虎影视.com | 日本亚洲国产精品久久 | 一区在线播放 | 国产香港特级一级毛片 |