新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > linux內核中的fastcall和asmlinkage宏

        linux內核中的fastcall和asmlinkage宏

        作者: 時間:2016-11-22 來源:網絡 收藏
        內核版本:2.6.14

        linux內核中我們都會經常見到FASTCALL和armlinkage,它們各有什么不同呢?下面我們來具體分析一下。

        本文引用地址:http://www.104case.com/article/201611/319989.htm

        在標準C系中函數的形參在實際傳入參數的時候會涉及到參數存放的問題,那么這些參數存放在哪里呢?對x86比較了解的話,應該知道這些函數參數和函數內部局部變量一起被分配到了函數的局部堆棧中。linux操作系統支持多種CPU架構,比如x86、ppc和arm等,在不同的處理器結構上不能保證都是通過 局部棧傳遞參數的。ARM對函數調用過程中的傳參定義了一套規則,即 ATPCS,規則中明確指出ARM中R0-R4都是作為通用寄存器使用,在函數調用時處理器從R0-R4中獲取參數,在函數返回時再 將需要返回的參數一次存到R0-R4中,也就是說可以將函數參數直接存放在寄存器中,所以為了嚴格區別函數參數的存放位置,引入了兩個標記,即 asmlinkage和FASTCALL,前者表示將函數參數存放在局部棧中,后者則是通知編譯器將函數參數用寄存器保存起來。

        1.x86平臺

        [plain]view plaincopy
        print?
        1. #defineasmlinkageCPP_ASMLINKAGE__attribute__((regparm(0)))
        2. #defineFASTCALL(x)x__attribute__((regparm(3)))
        3. #definefastcall__attribute__((regparm(3)))

        函數定義前加宏asmlinkage,表示這些函數通過堆棧而不是通過寄存器傳遞參數。gcc編譯器在匯編過程中調用c語言函數時傳遞參數有兩種方法:一種是通過堆棧,另一種是通過寄存器。缺省時采用寄存器,假如你要在你的匯編過程中調用c語言函數,并且想通過堆棧傳遞參數,你定義的c函數時要在函數前加上宏asmlinkage。

        其中 __attribute__是關鍵字,是gcc的c語言擴展。__attribute__機制是GNU C的一大特色,它可以設置函數屬性、變量屬性和類型屬性等。可以通過它們向編譯器提供更多數據,幫助編譯器執行優化等。
        __attribute__((regparm(0))):告訴gcc編譯器該函數不需要通過任何寄存器來傳遞參數,參數只是通過堆棧來傳遞。
        __attribute__((regparm(3))):告訴gcc編譯器這個函數可以通過寄存器傳遞多達3個的參數,這3個寄存器依次為EAX、EDX 和 ECX。更多的參數才通過堆棧傳遞。這樣可以減少一些入棧出棧操作,因此調用比較快。
        asmlinkage大都用在系統調用中。有一些情況下是需要明確的告訴編譯器,我們是使用stack來傳遞參數的,比如x86中的系統調用,是先將參數壓入stack以后調用sys_*函數的,所以所有的sys_*函數都有asmlinkage來告訴編譯器不要使用寄存器來編譯。

        2.arm平臺

        對于arm處理器的,沒有定義FASTCALL和armlinkage,所以沒有意義(對于ARM平臺來說,要符合ATPCS過程調用標準,即通過寄存器傳遞的。ARM中R0-R4用于存放傳入參數,所有函數的參數不應該大于5個,如果超過5個,多余的參數被存放到局部棧中。)。

        [plain]view plaincopy
        print?
        1. #ifndefFASTCALL
        2. #defineFASTCALL(x)x
        3. #definefastcall
        4. #endif
        5. #ifndefasmlinkage
        6. #defineasmlinkageCPP_ASMLINKAGE
        7. #endif

        3.CPP_ASMLINKAGE

        [plain]view plaincopy
        print?
        1. #ifdef__cplusplus
        2. #defineCPP_ASMLINKAGEextern"C"
        3. #else
        4. #defineCPP_ASMLINKAGE
        5. #endif

        extern "C" 包含雙重含義,從字面上即可得到:首先,被它修飾的目標是“extern”的;其次,被它修飾的目標是“C”的。
          (1) 被extern "C"限定的函數或變量是extern類型的extern是C/C++語言中表明函數和全局變量作用范圍(可見性)的關鍵字,該關鍵字告訴編譯器,其聲明的函數和變量可以在本模塊或其它模塊中使用。與extern對應的關鍵字是static,被它修飾的全局變量和函數只能在本模塊中使用。因此,一個函數或變量只可能被本模塊使用時,其不可能被extern “C”修飾。
          (2) 被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的。



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 海口市| 航空| 扎鲁特旗| 辛集市| 海伦市| 冀州市| 平阳县| 高平市| 江达县| 鄱阳县| 景宁| 湖口县| 景洪市| 二连浩特市| 晋中市| 张家界市| 财经| 江阴市| 武城县| 正宁县| 于田县| 且末县| 裕民县| 满洲里市| 安庆市| 寿宁县| 土默特左旗| 祥云县| 会泽县| 蓬安县| 洪湖市| 克东县| 侯马市| 罗平县| 阿城市| 共和县| 苍南县| 华蓥市| 澜沧| 五莲县| 永登县|