標題: C 語言當中內嵌 GNU 的組合語言 [列印本頁] 作者: mm117777 時間: 2012-7-9 09:33:08 標題: C 語言當中內嵌 GNU 的組合語言
有時,為了能增進程式的效率,或者在 C 語言當中加入一些組合語言程式碼,我們會採用內嵌的方式,將組合語言內嵌在C語言當中。針對這點,gcc提供了如圖 4.10的內嵌語法,讓我們在 C 語言中可以直接撰寫組合語言。其中,assembler template 為組合語言程式、output operands 為輸入參數、input operands 為輸入參數,而 list of clobbered registers 則指定了被更改的暫存器參數列表。
表格 4.1 GNU嵌入式組合語言的限制條件 (針對 IA32處理器)
限制 說明 限制 說明
A eax I (instant constant) 常數 (0到31 之間)
B ebx m (memory) 記憶體位址
C ecx r (register) 暫存器eax ebx ecx edx esi edi
D edx q eax ebx ecx edx
S esi g (general) eax,ebx, ecx, edx、變數或常數
D edi 0, 1, 2, … 參數 %0 %1 %2 ….
… … … …
利用表格 4.1中的限制條件,我們可以放寬暫存器的限制,改使用像 addl %2, %0 這樣的方式。這種方式可以讓編譯器自行選擇能使用的暫存器,如此,可以增進程式的效率。在範例 4.26中,我們就使用了此種參數指定的方式,利用 addl %2, %0 指令內嵌,然後,在輸出參數0 中指定 :"=r"(foo),這使得 foo 可使用的候選的暫存器放寬為 r 條件的『eax ebx ecx edx esi edi』。接著,在輸入參數 %1, %2中指定 :"0"(foo), "r"(bar),這同樣使得 bar 的候選暫存器放寬為r 條件的『eax ebx ecx edx esi edi』。但是,由於 foo 變數已經在輸出參數 :"=r"(foo)被指定了,因此,必須在第一個輸入參數的 (foo) 前加上 "0" 條件,告訴編譯器該參數所用的暫存器必須與 :"=r"(foo) 所選擇的一致,如此,就能讓編譯器有更多的選擇空間。範例 4.26顯示了我們將前述的內嵌組合語言之條件由 a, b 放寬為 r 之後的結果。
在本節中,我們已經介紹了如何使用 gcc 進行編譯、組譯與連結的方法,由於gcc是一個編譯、組譯與連結的萬用工具,因此,通常我們不會直接使用 GNU的 as 組譯器,而會改用 gcc 作為組譯器,以便與 C 語言程式進行連結,甚至在C語言當中直接內嵌組合語言,這讓我門不需要完全從組合語言開始撰寫,對系統程式的開發有相當大的用處,特別是嵌入式系統。