ARM匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞_第1頁(yè)
ARM匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞_第2頁(yè)
ARM匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞_第3頁(yè)
ARM匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞_第4頁(yè)
ARM匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、arm匯編語(yǔ)言調(diào)用C函數(shù)之參數(shù)傳遞 于ARM體系來(lái)說(shuō),不同語(yǔ)言撰寫(xiě)的函數(shù)之間相互調(diào)用(mix calls)遵循的是 ATPCS(ARM-Thumb Procedure Call Standard),ATPCS主要是定義了函數(shù)呼叫時(shí)參數(shù)的傳遞規(guī)則以及如何從函數(shù)返回,關(guān)于ATPCS的詳細(xì)內(nèi)容可以查看ADS1.2 Online Books Developer Guide的2.1節(jié)。這篇文檔要講的是 匯編代碼中對(duì)C函數(shù)調(diào)用時(shí)如何進(jìn)行參數(shù)的傳遞以及如何從C函數(shù)正確返回。   不同于x86的參數(shù)傳遞規(guī)則,ATPCS建議函數(shù)的形參不超過(guò)4

2、個(gè),如果形參個(gè)數(shù)少于或等于4,則形參由R0,R1,R2,R3四個(gè)寄存器進(jìn)行傳遞;若形參個(gè)數(shù)大于4,大于4的部分必須通過(guò)堆棧進(jìn)行傳遞。   我們先討論一下形參個(gè)數(shù)為4的情況. 實(shí)例1:test_asm_args.asm/-       IMPORT test_c_args ;聲明test_c_args函數(shù)       AREA TEST_ASM, CODE, READONLY   

3、0;   EXPORT test_asm_argstest_asm_args      STR lr, sp, #-4! ;保存當(dāng)前l(fā)r       ldr r0,=0x10      參數(shù) 1       ldr r1,=0x20     

4、0;參數(shù) 2       ldr r2,=0x30      參數(shù) 3       ldr r3,=0x40      參數(shù) 4       bl test_c_args    調(diào)用C函數(shù) 

5、     LDR pc, sp, #4   將lr裝進(jìn)pc(返回main函數(shù)       ENDtest_c_args.c/-void test_c_args(int a,int b,int c,int d       printk("test_c_args:n"       printk

6、("%0x %0x %0x %0xn",a,b,c,d;main.c/-int main(    test_asm_args(;    for(;    程序從main函數(shù)開(kāi)始執(zhí)行,main調(diào)用了test_asm_args,test_asm_args調(diào)用了test_c_args,最后從test_asm_args返回main。代碼分別使用了匯編和C定義了兩個(gè)函數(shù),test_asm_args 和 test_c_args,test_asm_a

7、rgs調(diào)用了test_c_args,其參數(shù)的傳遞方式就是向R0R3分別寫(xiě)入?yún)?shù)值,之后使用bl語(yǔ)句 對(duì)test_c_args進(jìn)行調(diào)用。其中值得注意的地方是用紅色標(biāo)記的語(yǔ)句,test_asm_args在調(diào)用test_c_args之前必須把當(dāng)前的 lr入棧,調(diào)用完test_c_args之后再把剛才保存在棧中的lr寫(xiě)回pc,這樣才能返回到main函數(shù)中。   如果test_c_args的參數(shù)是8個(gè)呢?這種情況test_asm_args應(yīng)該怎樣傳遞參數(shù)呢?實(shí)例2:test_asm_args.asm/-    &#

8、160;  IMPORT test_c_args ;聲明test_c_args函數(shù)       AREA TEST_ASM, CODE, READONLY       EXPORT test_asm_argstest_asm_args   STR lr, sp, #-4! ;保存當(dāng)前l(fā)r   ldr r0,=0x1 ;參數(shù) 1   ldr

9、 r1,=0x2 ;參數(shù) 2   ldr r2,=0x3 ;參數(shù) 3   ldr r3,=0x4 ;參數(shù) 4   ldr r4,=0x8   str r4,sp,#-4! ;參數(shù) 8 入棧   ldr r4,=0x7   str r4,sp,#-4! ;參數(shù) 7 入棧   ldr r4,=0x6  

10、 str r4,sp,#-4! ;參數(shù) 6 入棧   ldr r4,=0x5   str r4,sp,#-4! ;參數(shù) 5 入棧   bl test_c_args_lots   ADD sp, sp, #4    清除棧中參數(shù) 5,本語(yǔ)句執(zhí)行完后sp指向 參數(shù)6   ADD sp, sp, #4   

11、0;清除棧中參數(shù) 6,本語(yǔ)句執(zhí)行完后sp指向 參數(shù)7   ADD sp, sp, #4    清除棧中參數(shù) 7,本語(yǔ)句執(zhí)行完后sp指向 參數(shù)8   ADD sp, sp, #4    清除棧中參數(shù) 8,本語(yǔ)句執(zhí)行完后sp指向 lr   LDR pc, sp,#4 ;將lr裝進(jìn)pc(返回main函數(shù)   ENDtest_c_args.c/-

12、void test_c_args(int a,int b,int c,int d,int e,int f,int g,int h   printk("test_c_args_lots:n"   printk("%0x %0x %0x %0x %0x %0x %0x %0xn",      a,b,c,d,e,f,g,h;main.c/-int main(    test_asm_args(;

13、60;   for(; 這部分的代碼和實(shí)例1的代碼大部分是相同的,不同的地方是test_c_args的參數(shù)個(gè)數(shù)和test_asm_args的參數(shù)傳遞方式。在test_asm_args中,參數(shù)1參數(shù)4還是通過(guò)R0R3進(jìn)行傳遞,而參數(shù)5參數(shù)8則是通過(guò)把其壓入堆棧的方式進(jìn)行傳遞,不過(guò)要注意這四個(gè)入棧參數(shù)的入棧順序,是以參數(shù)8->參數(shù)7->參數(shù)6->參數(shù)5的順序入棧的。直到調(diào)用test_c_args之前,堆棧內(nèi)容如下:sp->+-+       |  

14、; 參數(shù)5   |   +-+       |   參數(shù)6   |   +-+       |   參數(shù)7   |   +-+       

15、|   參數(shù)8   |   +-+       |   lr   |   +-+test_c_args執(zhí)行返回后,則設(shè)置sp,對(duì)之前入棧的參數(shù)進(jìn)行清除,最后將lr裝入pc返回main函數(shù),在執(zhí)行 LDR pc, sp,#4 指令之前堆棧內(nèi)容如下:   +-+   

16、60;   |   參數(shù)5   |   +-+       |   參數(shù)6   |   +-+       |   參數(shù)7   |   +-+ 

17、60;     |   參數(shù)8   |sp->+-+       |   lr   |   +-+基于ARM的C語(yǔ)言與匯編語(yǔ)言混合編程1、C語(yǔ)言與匯編語(yǔ)言混合編程應(yīng)遵守的規(guī)則ARM編程中使用的C語(yǔ)言是標(biāo)準(zhǔn)C語(yǔ)言,ARM的開(kāi)發(fā)環(huán)境實(shí)際上就是嵌入了一個(gè)C語(yǔ)言的集成開(kāi)發(fā)環(huán)境,只不過(guò)這個(gè)開(kāi)發(fā)環(huán)境與ARM的硬件緊密相關(guān)。在使用C語(yǔ)言

18、時(shí),要用到和匯編語(yǔ)言的混合編程。若匯編代碼較為簡(jiǎn)潔,則可使用直接內(nèi)嵌匯編的方法;否則要將匯編程序以文件的形式加入到項(xiàng)目中,按照ATPCS(ARM/Thumb過(guò)程調(diào)用標(biāo)準(zhǔn),ARM/Thumb Procedure Call Standard的規(guī)定與C程序相互調(diào)用與訪問(wèn)。在C程序和ARM匯編程序之間相互調(diào)用時(shí)必須遵守ATPCS規(guī)則。ATPCS規(guī)定了一些子程序間調(diào)用的基本規(guī)則,哪寄存器的使用規(guī)則,堆棧的使用規(guī)則和參數(shù)的傳遞規(guī)則等。1寄存器的使用規(guī)則子程序之間通過(guò)寄存器r0r3來(lái)傳遞參數(shù),當(dāng)參數(shù)個(gè)數(shù)多于4個(gè)時(shí),使用堆棧來(lái)傳遞參數(shù)。此時(shí)r0r3可記作A1A4。在子程序中,使用寄存器r4r11保存局部變量。

19、因此當(dāng)進(jìn)行子程序調(diào)用時(shí)要注意對(duì)這些寄存器的保存和恢復(fù)。此時(shí)r4r11可記作V1V8。寄存器r12用于保存堆棧指針SP,當(dāng)子程序返回時(shí)使用該寄存器出棧,記作IP。寄存器r13用作堆棧指針,記作SP。寄存器r14稱(chēng)為鏈接寄存器,記作LR。該寄存器用于保存子程序的返回地址。寄存器r15稱(chēng)為程序計(jì)數(shù)器,記作PC。2堆棧的使用規(guī)則ATPCS規(guī)定堆棧采用滿遞減類(lèi)型(FD,Full Descending,即堆棧通過(guò)減小存儲(chǔ)器地址而向下增長(zhǎng),堆棧指針指向內(nèi)含有效數(shù)據(jù)項(xiàng)的最低地址。3參數(shù)的傳遞規(guī)則整數(shù)參數(shù)的前4個(gè)使用r0r3傳遞,其他參數(shù)使用堆棧傳遞;浮點(diǎn)參數(shù)使用編號(hào)最小且能夠滿足需要的一組連續(xù)的FP寄存器傳遞

20、參數(shù)。子程序的返回結(jié)果為一個(gè)32位整數(shù)時(shí),通過(guò)r0返回;返回結(jié)果為一個(gè)64位整數(shù)時(shí),通過(guò)r0和r1返回;依此類(lèi)推。結(jié)果為浮點(diǎn)數(shù)時(shí),通過(guò)浮點(diǎn)運(yùn)算部件的寄存器F0、D0或者S0返回。2、匯編程序調(diào)用C程序的方法匯編程序的書(shū)寫(xiě)要遵循ATPCS規(guī)則,以保證程序調(diào)用時(shí)參數(shù)正確傳遞。在匯編程序中調(diào)用C程序的方法為:首先在匯編程序中使用IMPORT偽指令事先聲明將要調(diào)用的C語(yǔ)言函數(shù);然后通過(guò)BL指令來(lái)調(diào)用C函數(shù)。例如在一個(gè)C源文件中定義了如下求和函數(shù):int add(int x,int yreturn(x+y;調(diào)用add(函數(shù)的匯編程序結(jié)構(gòu)如下:IMPORT add ;聲明要調(diào)用的C函數(shù)MOV r0,1MO

21、V r1,2BL add ;調(diào)用C函數(shù)add當(dāng)進(jìn)行函數(shù)調(diào)用時(shí),使用r0和r1實(shí)現(xiàn)參數(shù)傳遞,返回結(jié)果由r0帶回。函數(shù)調(diào)用結(jié)束后,r0的值變成3。3、C程序調(diào)用匯編程序的方法C程序調(diào)用匯編程序時(shí),匯編程序的書(shū)寫(xiě)也要遵循ATPCS規(guī)則,以保證程序調(diào)用時(shí)參數(shù)正確傳遞。在C程序中調(diào)用匯編子程序的方法為:首先在匯編程序中使用EXPORT偽指令聲明被調(diào)用的子程序,表示該子程序?qū)⒃谄渌募斜徽{(diào)用;然后在C程序中使用extern關(guān)鍵字聲明要調(diào)用的匯編子程序?yàn)橥獠亢瘮?shù)。例如在一個(gè)匯編源文件中定義了如下求和函數(shù):EXPORT add ;聲明add子程序?qū)⒈煌獠亢瘮?shù)調(diào)用add ;求和子程序addADD r0,r0,r1MOV pc,lr在一個(gè)C程序的main(函數(shù)中對(duì)add匯編子程序進(jìn)行了調(diào)用:extern int add (int x,int y; /聲明add為外部函數(shù)void main(int a=1,b=2,c;c=add(a,b; /調(diào)用add子程序當(dāng)main(函數(shù)調(diào)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論