嵌入式Linux下C和匯編的混合編程_第1頁
嵌入式Linux下C和匯編的混合編程_第2頁
嵌入式Linux下C和匯編的混合編程_第3頁
嵌入式Linux下C和匯編的混合編程_第4頁
嵌入式Linux下C和匯編的混合編程_第5頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、2.6嵌入式Linux下C和匯編的混合編程2.6.1混合編程概述C和匯編的混合編程及類型C語言是被稱為高級(jí)的低級(jí)語言,原因是在C語言中,有許多針對(duì)硬件的操作,能很好地 利用硬件特性。從一方面來說,C語言也是高級(jí)語言,它能很方便地實(shí)現(xiàn)各種復(fù)雜的編程算 法。在嵌入式系統(tǒng)編程中,C語言是首選的程序設(shè)計(jì)語言,但在某些特定條件下,C語言無法 精確地操作硬件,此時(shí)往往采用嵌入或調(diào)用匯編程序的方法來解決此類問題。這就是混合編 程?;旌暇幊虖姆绞缴现饕ㄈ?,即:C程序調(diào)用匯編程序;匯編程序調(diào)用C程序;C程 序內(nèi)嵌匯編。本文后續(xù)將分別介紹這三類編程方法。ATPCS規(guī)范簡(jiǎn)介基于ARM的嵌入式C和匯編的混合編程

2、需要遵循一定的規(guī)范,這就是過程調(diào)用標(biāo)準(zhǔn)ATPCS 規(guī)范。ATPCS規(guī)定了子程序間相互調(diào)用的基本規(guī)則,調(diào)用過程中寄存器的使用規(guī)則、數(shù)據(jù)棧 的使用規(guī)則及參數(shù)的傳遞規(guī)則。2007年,ARM公司推出了新的過程調(diào)用標(biāo)準(zhǔn)AAPCS(ARM Architecture Produce Call Standard),它只是改進(jìn)了原有的ATPCS的二進(jìn)制代碼的兼容性。 這里簡(jiǎn)單介紹寄存器的使用規(guī)則、數(shù)據(jù)棧的使用規(guī)則、參數(shù)的傳遞規(guī)則和子程序結(jié)果返回規(guī) 則,更詳細(xì)的內(nèi)容請(qǐng)參考其它參考資料。寄存器使用規(guī)則子程序間通過寄存器R0R3傳遞參數(shù),寄存器R0R3可記作A1A4。被調(diào)用的子程 序在返回前無須恢復(fù)寄存器R0R3的內(nèi)

3、容。在子程序中,ARM狀態(tài)下使用寄存器R4R11來保存局部變量,寄存器R4R11可記 作V1V8 ; Thumb狀態(tài)下只能使用R4R7來保存局部變量。寄存器R12用作子程序間調(diào)用時(shí)臨時(shí)保存棧指針,函數(shù)返回時(shí)使用該寄存器進(jìn)行出 棧,記作IP ;在子程序間的鏈接代碼中常有這種使用規(guī)則。通用寄存器R13用作數(shù)據(jù)棧指針,記作SP0通用寄存器R14用作鏈接寄存器。通用寄存器R15用作程序計(jì)數(shù)器,記作PC。數(shù)據(jù)棧使用規(guī)則過程調(diào)用標(biāo)準(zhǔn)規(guī)定數(shù)據(jù)棧為FD (Full descending滿遞減堆棧)類型,并且對(duì)數(shù)據(jù) 棧的操作時(shí)要求8字節(jié)對(duì)齊的。參數(shù)傳遞規(guī)則參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則對(duì)于參數(shù)個(gè)數(shù)可變的子程序

4、,當(dāng)參數(shù)個(gè)數(shù)不超過4個(gè)時(shí),可以使用寄存器R0R3來 傳遞;當(dāng)參數(shù)個(gè)數(shù)超過4個(gè)時(shí),還可以使用數(shù)據(jù)棧進(jìn)行參數(shù)傳遞。參數(shù)個(gè)數(shù)固定的子程序參數(shù)傳遞規(guī)則如果系統(tǒng)不包含浮點(diǎn)運(yùn)算的硬件部件且沒有浮點(diǎn)參數(shù)時(shí),則依次將各參數(shù)傳送到寄存器R0R3中,如果參數(shù)個(gè)數(shù)多于4個(gè),將剩余的字?jǐn)?shù)據(jù)通過數(shù)據(jù)棧來傳遞;如果包括浮點(diǎn)參數(shù)則要通過相應(yīng)的規(guī)則將浮點(diǎn)參數(shù)轉(zhuǎn)換為整數(shù)參數(shù),然后依次將各 參數(shù)傳送到寄存器R0R3中。如果參數(shù)多于4個(gè),將剩余字?jǐn)?shù)據(jù)傳送到數(shù)據(jù)棧中, 入棧的順序與參數(shù)順序相反,即最后一個(gè)字?jǐn)?shù)據(jù)先入棧。子程序結(jié)果返回規(guī)則結(jié)果為一個(gè)32位的整數(shù)時(shí),通過寄存器0返回;結(jié)果為一個(gè)64位整數(shù)時(shí),通過寄存 器R0,R1返回。結(jié)

5、果為一個(gè)浮點(diǎn)數(shù)時(shí),可以通過浮點(diǎn)運(yùn)算部件的寄存器F0、D0或者S0來返回;結(jié)果 為復(fù)合型的浮點(diǎn)數(shù)(如復(fù)數(shù))時(shí),可以通過寄存器F0-Fn或者D0Dn來返回。對(duì)于位數(shù)更多的結(jié)果,需要通過內(nèi)存來傳遞。ARM開發(fā)工具編譯環(huán)境和GNU編譯環(huán)境的差別ARM開發(fā)工具編譯環(huán)境(如ads )和GNU編譯環(huán)境下內(nèi)嵌匯編的格式和偽操作是不同的。 后文將不介紹ARM開發(fā)工具編譯環(huán)境下的混合編程實(shí)現(xiàn),但是,讀者對(duì)于兩者的偽操作上區(qū)別還是需要了解的,以便在需要的時(shí)候?qū)RM開發(fā)工具編譯環(huán)境下的匯編移植到GNU編譯環(huán)境 下。表2.18給出了兩者常用偽操作的對(duì)應(yīng)關(guān)系。ARM偽操作符GNU偽操作符ARM偽操作符GNU偽操作符IN

6、CLUDE.includeRN.reqEXPORT.globalGBLA.globalIMPORT.externMACRO.marcoDCD.longEND.endIF:DEF:.ifdefAREA Word,CODE, READONLY.textELSE.elseAREA Block,DATA, READWRITE.dataENDIF.endifCODE32.arm:OR:CODE16.thumb:SHLEntryEntry:另外,對(duì)于注釋,在ARM開發(fā)工具編譯環(huán)境中注釋行以“;”開始。GNU環(huán)境注釋行以“時(shí) 開始,行較多時(shí)將內(nèi)容放在“/*”和“*/”之間。2.6.2 C調(diào)用匯編在C中調(diào)用匯

7、編文件中的函數(shù),要做的主要工作有兩個(gè),一是任中聲明函數(shù)原型,并 加extern關(guān)鍵字;二是在匯編中用global導(dǎo)出函數(shù)名,并用該函數(shù)名作為匯編代碼段的標(biāo)識(shí), 最后用mov pc, lr返回。然后,就可以在C中使用該函數(shù)了。從。的角度,并不知道該函數(shù) 的實(shí)現(xiàn)是用C還是匯編。更深的原因是因?yàn)镃的函數(shù)名起到表明函數(shù)代碼起始地址的作用, 這個(gè)和匯編的label是一致的。以下給出一個(gè)調(diào)用的例子,程序包括兩個(gè)文件:main.c和Asmfile_gnu.s。main.c用c實(shí) 現(xiàn),包含主函數(shù),負(fù)責(zé)調(diào)用Asmfile_gnu.c的global asmDouble,并將調(diào)用前后的值輸出; Asmfile_gn

8、u.c用ARM匯編實(shí)現(xiàn),包含被調(diào)用函數(shù)“global asmDouble”,實(shí)現(xiàn)整數(shù)的倍乘。main.c:#include int gVar_1 = 12;extern asmDouble(void);int main()printf(original value of gVar_1 is: %d, gVar_1); asmDouble();printf( modified value of gVar_1 is: %d, gVar_1); return 0;Asmfile_gnu.s:#called by main(in C),to double an integer, a global va

9、r defined in C is used .text.global asmDouble.extern gVar_1asmDouble:ldr r0, =gVar_1ldr r1, r0mov r2, #2mul r3, r1, r2str r3, r0mov pc, lr.end以上程序通過使用全局變量gVar_ 1實(shí)現(xiàn)匯編和C之間數(shù)據(jù)的傳遞,這是最簡(jiǎn)單的調(diào)用方 式了。對(duì)以上程序加以修改,以實(shí)現(xiàn)匯編和C之間參數(shù)的傳遞,如下:main.c:#include extern int asmMulti(int,int);int main()int x=5;int y=6;int z;printf(

10、nx=%d, y=%d,x,y);z=asmMulti(x,y);printf(n x*y=%dn, z);return 0Asmfile_gnu.s:y) 時(shí),參數(shù)x傳遞給了r0;參數(shù)y傳遞給了r1。在匯編程序中,r0、r1的乘積賦給r2后再賦給r0, 因?yàn)閞0最終作為主函數(shù)調(diào)用的返回值。在這里,C和匯編之間的參數(shù)傳遞是通過ATPCS的規(guī) 定來進(jìn)行的。簡(jiǎn)單的說就是如果函數(shù)有不多于四個(gè)參數(shù),對(duì)應(yīng)的用0求3來進(jìn)行傳遞,多于 4個(gè)時(shí)借助棧。函數(shù)的返回值通過R0來返回。2.6.3匯編調(diào)用C在匯編中調(diào)用C的函數(shù),需要在匯編中使用extern聲明對(duì)應(yīng)的C函數(shù)名,然后將C的代碼 放在一個(gè)獨(dú)立的C文件中進(jìn)行編譯,剩下的工作由連接器來處理。cFile.c:int cFun(int a, int b, int c)return a + b + c;Asmfile_gnu.s:#the details of parameters transfer

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論