版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、.,第6章 arm程序設(shè)計,本章的主要內(nèi)容,1、arm匯編語言程序設(shè)計,2、arm程序的框架結(jié)構(gòu),3、c語言程序?qū)R編程序的調(diào)用,4、arm與c語言混合程序設(shè)計,.,6.1 arm工程,由于c語言便于理解,有大量的支持庫,所以它是當前arm程序設(shè)計所使用的主要編程語言。,對硬件系統(tǒng)的初始化、cpu狀態(tài)設(shè)定、中斷使能、主頻設(shè)定以及ram控制參數(shù)初始化等c程序力所不能及的底層操作,還是要由匯編語言程序來完成。,.,用匯編語言或c/c+語言編寫的程序叫做源程序,對應(yīng)的文件叫做源文件。,一個arm工程應(yīng)由多個文件組成,其中包括擴展名為.s的匯編語言源文件、擴展名為.c的c語言源文件,擴展名為.cpp的
2、c+源文件、擴展名為.h的頭文件等。,arm工程的各種源文件之間的關(guān)系,以及最后形成可執(zhí)行文件的過程如下:,.,匯編語言 源文件,匯編器,目標文件,c/c+語言 源文件,編譯器,目標文件,頭文件,c/c+庫文件,連接器,可執(zhí)行文件,.,arm提供的開發(fā)工具code warrior for arm中包含的編譯器如下:,.,除了c和c+編譯器,code warrior for arm開發(fā)工具還提供了匯編器armasm。,編譯器負責生成目標文件,它是一種包含了調(diào)試信息的elf格式文件。,編譯器還要生成列表文件等相關(guān)文件:,.,.,各種源文件先由編譯器和匯編器將它們分別編譯或匯編成匯編語言文件及目標文
3、件。,連接器負責將所有目標文件連接成一個文件并確定各指令的確定地址,從而形成最終可執(zhí)行文件。,連接器有三個功能:,.,(1)生成與地址相關(guān)的代碼,把所有文件連接成一個可執(zhí)行文件。,(2)根據(jù)程序員所指定的選項,為程序分配地址空間。,(3)給出連接信息,以說明連接過程和連接結(jié)果。,.,6.2 arm匯編語言程序設(shè)計,6.2.1 段,匯編語言編寫的程序叫做匯編語言源程序,包含源程序的文件叫做匯編語言程序文件。,一個工程可以有多個源文件,匯編源文件的擴展名為.s。,.,在arm(thumb)匯編語言程序中,通常以段為單位來組織代碼。段是具有特定名稱且功能相對獨立的指令或數(shù)據(jù)序列。,根據(jù)段的內(nèi)容,分為
4、代碼段和數(shù)據(jù)段。,一個匯編程序至少應(yīng)該有一個代碼段,當程序較長時,可以分割為多個代碼段和數(shù)據(jù)段。,.,以下是一個匯編語言程序段的基本結(jié)構(gòu):,area init, code, readonly /只讀的代碼段init entry /程序入口點 start ldr r0,#0x3ff5000 ldr r1,0xff str r1,r0 ldr r0,#0x3ff5008 ldr r1,0x01 str r1,r0 . end /段結(jié)束,.,6.2.2 分支程序設(shè)計,具有兩個或兩個以上可選執(zhí)行路徑的程序叫做分支程序。,1、普通分支程序設(shè)計,使用帶有條件碼的指令可以很容易地實現(xiàn)分支程序。,.,例:編寫
5、一個分支程序段,如果寄存器r5中的數(shù)據(jù)等于10,就把r5中的數(shù)據(jù)存如寄存器r1;否則把r5中的數(shù)據(jù)分別存儲寄存器r0和r1。,.,(1)用條件指令實現(xiàn)的分支程序段,cmp r5,#10 movne r0,r5 mov r1,r5,(2)用條件轉(zhuǎn)移指令來實現(xiàn)分支,cmp r5,#10 beq doequal mov r0,r5 doequal mov r1,r5,.,例:編寫一個程序段,當寄存器r1中的數(shù)據(jù)大于r2中數(shù)據(jù)時,將r2中的數(shù)據(jù)加10存入寄存器r1;否則將r2中數(shù)據(jù)加5存入寄存器r1。,.,cmp r1,r2 addhi r1,r2,#10 addls r1,r2,#5,2、多分支(散
6、轉(zhuǎn))程序設(shè)計,程序分支點上有多于兩個以上的執(zhí)行路徑的程序叫做多分支程序。利用條件測試指令或跳轉(zhuǎn)表可以實現(xiàn)多分支程序。,.,例、編寫一個程序段,判斷寄存器r1中數(shù)據(jù)是否為10、15、12、22。如果是,則將r0中的數(shù)據(jù)加1;否則將r0設(shè)置為0xf。,.,mov r0,#0 teq r1,#10 teqne r1,#15 teqne r1,#12 teqne r1,#22 addeq r0,r0,#1 movne r0,#0xf,.,當多分支程序的每個分支所對應(yīng)的是一個程序段時,常常把各個分支程序段的首地址依次存放在一個叫做跳轉(zhuǎn)地址表的存儲區(qū)域,然后在程序的分支點處使用一個可以將跳轉(zhuǎn)表中的目標地址
7、傳送到pc的指令來實現(xiàn)分支。,一個具有3個分支的跳轉(zhuǎn)地址表示意圖如下:,.,.,mov r0,n adr r5,jptb ldr pc,r5,r0,lsl #2 jptab ;跳轉(zhuǎn)表 dcd fun0 dcd fun1 ecd fun2 fun0 . ;分支fun0的程序段 fun1 . ;分支fun1的程序段 fun2 . ;分支fun2的程序段,.,3、帶arm/thumb狀態(tài)切換的分支程序設(shè)計,在arm程序中經(jīng)常需要在程序跳轉(zhuǎn)的同時還要進行處理器狀態(tài)的轉(zhuǎn)移,即從arm指令程序段跳轉(zhuǎn)到thumb指令程序段(或相反)。為了實現(xiàn)這個功能,系統(tǒng)提供了一條專用的、可以實現(xiàn)4gb空間范圍內(nèi)的絕對跳轉(zhuǎn)
8、交換指令bx。,.,.,下面是一段從arm指令程序段跳轉(zhuǎn)到thumb指令程序的狀態(tài)切換例程。,;arm指令程序 code32 . add r0,into_thumb +1 bx r0 . ;thumb指令程序 code16 into_thumb .,.,下面是一段從thumb 指令程序段跳轉(zhuǎn)到arm指令程序的狀態(tài)切換例程。,; thumb 指令程序 code16 . add r5,back_to_arm bx r0 . ; arm指令程序 code32 back_to_arm .,.,6.2.3 循環(huán)程序設(shè)計,當條件滿足時,需要重復執(zhí)行同一個程序段做同樣工作的程序叫做循環(huán)程序。,被重復執(zhí)行的程
9、序段叫做循環(huán)體,需要滿足的條件叫做循環(huán)條件。,循環(huán)程序有兩種結(jié)構(gòu):do-while結(jié)構(gòu)和do-until結(jié)構(gòu)。,.,do-while結(jié)構(gòu),do-until結(jié)構(gòu),.,在匯編語言程序設(shè)計中,常用的是do-until結(jié)構(gòu)循環(huán)程序。,mov r1,#10 loop . sub r1,r1,#1 bne loop,例、編寫一個程序,把首地址為data_src的80個字的數(shù)據(jù)復制到首地址為data_dst的目標數(shù)據(jù)塊中。,.,ldr r1,#data_src ldr r0,#data_dst mov r10,#10 loop ldmia r1!,r2-r9 stmia r0!,r2-r9 subs r10
10、,r10,#1 bne loop,6.2.4 子程序及其調(diào)用,.,1、子程序的調(diào)用與返回,人們把這種可以多次反復調(diào)用的、能完成指定功能的程序段稱為“子程序”。把調(diào)用子程序的程序稱為“主程序”。,為進行識別,子程序的第1條指令之前必須賦予一個標號,以便其他程序可以用這個標號調(diào)用子程序。,.,在arm匯編語言程序中,主程序一般通過bl指令來調(diào)用子程序。該指令在執(zhí)行時完成如下操作:將子程序的返回地址存放在連接寄存器lr中,同時將程序計數(shù)器pc指向子程序的入口點。,為使子程序執(zhí)行完畢能返回主程序的調(diào)用處,子程序末尾處應(yīng)有mov、b、bx、stmfd等指令,并在指令中將返回地址重新復制到pc中。,.,在
11、調(diào)用子程序的同時,也可以使用r0r3來進行參數(shù)的傳遞和從子程序返回運算結(jié)果。,例、一個使用mov指令實現(xiàn)返回的子程序。,relay . mov pc, lr,使用b指令實現(xiàn)返回的子程序。,relay . b lr,.,例、一個使用bl指令調(diào)用子程序的匯編語言緣程序的基本結(jié)構(gòu)。,aera init, code, readonly entry start ldr r0,#0x3ff5000 ldr r1,0xff str r1,r0 ldr r0,#0x3ff5008 ldr r1,0x01 str r1,r0 bl pr .,.,pr mov pc,lr end,2、子程序中堆棧的使用,rela
12、y stmfd r13!,r0r12,lr;壓入堆棧 ;子程序代碼 ldmfd r13!,r0r12,pc ;彈出堆棧并返回,.,6.2.5 匯編程序訪問全局c變量,一般來說,匯編語言程序與c語言程序不在同一個文件上,所以實質(zhì)上這是一個引用不同文件定義的變量問題。解決這個問題的辦法就是使用關(guān)鍵字import和export。,例、下面是一個匯編代碼的函數(shù),它引用了一個在其他文件中定義的全局變量globvar,將其加2后寫回globvar 。,.,area globvar, code, readonly export asmsubrouttine import globvar asmsubrout
13、tine ldr r1,# globvar ldr r0,r1 add r0,r0,#2 str r0,r1 mov pc,lr end,.,6.3 arm程序框架,在應(yīng)用系統(tǒng)的程序設(shè)計中,若所有的編程任務(wù)均用匯編語言來完成,其工作量是可想而知的,這樣做也不利于系統(tǒng)升級或應(yīng)用軟件移植。,通常匯編語言部分完成系統(tǒng)硬件的初始化;高級語言部分完成用戶的應(yīng)用。,.,執(zhí)行時,首先執(zhí)行初始化部分,然后再跳轉(zhuǎn)到c/c+部分。整個程序結(jié)構(gòu)顯得清晰明了,容易理解。程序的基本結(jié)構(gòu)如下:,硬件初始化的匯編語 言程序(特權(quán)模式) b main,完成用戶任務(wù)的 c/c+程序(用戶模式),跳轉(zhuǎn),.,6.3.1 初始化程序
14、部分,由于在用于完成初始化任務(wù)的匯編語言程序中需要在特權(quán)模式下做一些諸如修改cpsr等特權(quán)操作,所以不能過早地進入用戶模式。,通常,初始化過程大致會經(jīng)歷如下所示的一些模式變化。,.,啟動,管理模式svc,其他特權(quán)模式,用戶模式usr,匯編語言 程序段,.,6.3.2初始化部分與主應(yīng)用程序部分的銜接,當所有的系統(tǒng)初始化工作完成之后,就需要把程序流程轉(zhuǎn)入主應(yīng)用程序。最簡單的方法是,在匯編語言程序末尾使用跳轉(zhuǎn)指令b或bl直接從啟動代碼轉(zhuǎn)移到c/c+程序入口。,b main ;跳轉(zhuǎn)到c/c+程序,.,同時在匯編文件中有如下代碼: import main,完整的匯編語言程序如下:,import main
15、 area init, code, readonly entry ldr r0,#0x3ff000 ldr r1,#0xe7ffff80 str r1,r0 ldr sp,#0x3ee1000 bl main end,.,c程序如下:,void main(void) . ,6.3.3 arm開發(fā)環(huán)境提供的程序框架,.,為方便工程開發(fā),arm公司的開發(fā)環(huán)境arm ads為用戶提供了一個可以選用的應(yīng)用程序框架。該框架把為用戶程序做準備工作的程序分成了啟動代碼和應(yīng)用程序初始化兩部分。,用于硬件初始化的匯編語言部分叫做啟動代碼;用于應(yīng)用程序初始化的c部分叫做初始化部分。整個程序如下所示:,.,impo
16、rt_main 啟動代碼 b_main,應(yīng)用程序初始化,主用程序,_main(),main(),.,6.4 c與匯編之間的函數(shù)調(diào)用,在arm工程中,c程序調(diào)用匯編函數(shù)和匯編程序調(diào)用c函數(shù)是經(jīng)常發(fā)生的事情。為此人們制定了arm-thumb過程調(diào)用標準atpcs(arm-thumb procedure call standard)。,6.4.1 atpcs簡介,.,1、堆棧與寄存器在函數(shù)調(diào)用中的作用,函數(shù)是通過寄存器和堆棧來傳遞參數(shù)和返回函數(shù)值的。,下面是c語言程序調(diào)用c函數(shù)的情況。,int addint(int x, int y) int s; s = x + y; return s; ,.,在
17、c程序中,主函數(shù)main()調(diào)用該函數(shù)的方法如下:,void main(void) . addint(a,b); /調(diào)用 ,.,arm編譯器使用的函數(shù)調(diào)用規(guī)則就是atpcs標準。atpcs標準既是arm編譯器的規(guī)則,也是設(shè)計可被c程序調(diào)用的匯編函數(shù)的編寫規(guī)則。,2、atpcs關(guān)于堆棧和寄存器的使用規(guī)則,atpcs規(guī)定,arm的數(shù)據(jù)堆棧為fd型堆棧,即遞減滿堆棧。,.,atpcs標準規(guī)定,對于參數(shù)個數(shù)不多于4的函數(shù),編譯器必須按參數(shù)在列表中的順序,自左向右為它們分配寄存器r0r3。其中函數(shù)返回時,r0還被用來存放函數(shù)的返回值。,.,如果函數(shù)的參數(shù)多于4個,那么多余的參數(shù)則按自右向做的順序壓入數(shù)據(jù)
18、堆棧,即參數(shù)入棧順序與采納書順序相反。,.,下表列舉了arm-thumb過程調(diào)用標準規(guī)定的寄存器的名稱和使用方法。,.,寄存器的別名和特殊名稱都是arm編譯器和匯編器預(yù)定義的,用戶可以直接使用。,6.4.2 c程序可調(diào)用匯編函數(shù)實例,下面是一個用匯編語言編寫的函數(shù),該函數(shù)把r1指向的數(shù)據(jù)塊復制到r0指向的存儲快。,.,area strcopy, code, readonly export strcopy strcopy ldrb r2,r1,#1 strb r2,r0,#1 cmp r2,#0 bne strcopy mov pc,lr end,.,根據(jù)atpcs的c語言程序調(diào)用匯編函數(shù),參數(shù)
19、由左向右依次傳遞給寄存器r0r3的規(guī)則,可知匯編函數(shù)strcopy在c程序中原型應(yīng)該為:,void strcopy(char *d, const char *s);,在c語言文件中,調(diào)用strcopy函數(shù)的方法如下:,.,extern void strcopy(char *d, const char *s); int main(void) const char *src = “source”; char dest10; . strcopy(dest, src; . ,.,6.4.3 匯編程序調(diào)用c函數(shù)實例,現(xiàn)有c函數(shù)g()如下:,int g(int a, int b, int c, int d
20、, int e) return a+b+c+d+e; ,匯編函數(shù)f中調(diào)用c函數(shù)g(),以實現(xiàn)下面的功能。,.,整個匯編函數(shù)f的代碼如下:,int f(int i) return g(i, 2*i, 3*i, 4*i,5*i),export f area f, code, readonly import g ;聲名g為外部引用符號 str lr, sp,#-4 ;斷點存入堆棧 add r1,r0,r0 ;(r1)= i*2 add r2,r1,r0 ; (r2)= i*3 add r3,r1,r2 ; (r3)= i*5 str r3,sp,#-4 ;將(r3)即第5個參數(shù)i*5存入堆棧 add
21、 r3,r1,r1 ;(r3)= i*4,.,bl g ;調(diào)用c函數(shù)g(),返回值在寄存器r0中 add sp,sp,#4 ;清棧 rsb r0,r0,#0 ;函數(shù)f的返回值(r0)=0-(r0) ldr pc,sp,#4 ;恢復斷點并返回 end,.,6.5 c/c+語言和匯編語言的混合編程,除了上面介紹的函數(shù)調(diào)用方法之外,arm編譯器armcc中含有內(nèi)嵌匯編器還允許在c程序中內(nèi)聯(lián)或嵌入式匯編代碼,以提高程序的效率。,6.5.1 內(nèi)聯(lián)匯編,1、定義內(nèi)聯(lián)匯編程序,.,所謂內(nèi)聯(lián)匯編程序,就是在c程序中直接編寫匯編程序段而形成一個語句塊,這個語句塊可以使用除了bx和blx之外的全部arm指令來編寫
22、,從而可以使程序?qū)崿F(xiàn)一些不能從c獲得的底層功能。,其格式為:,_asm 匯編語句塊 ,.,例: void enable_irq(void) int tmp; _asm /聲名內(nèi)聯(lián)匯編代碼 mrs tmp, cpsr bic tmp, tmp, #0 x80 msr cpsr_c, tmp ,.,2、內(nèi)聯(lián)匯編的限制,內(nèi)聯(lián)匯編與真實匯編之間有很大區(qū)別,會受到很多限制。,(1)它不支持thumb指令;除了程序狀態(tài)寄存器psr之外,不能直接訪問其他任何物理寄存器等。,(2)如果在內(nèi)聯(lián)匯編程序指令中出現(xiàn)了以某個寄存器名稱命名的操作數(shù),那么它,.,被叫做虛擬寄存器,而不是實際的物理寄存器。編譯器在生成和優(yōu)
23、化代碼的過程中,會給每個虛擬寄存器分配實際的物理寄存器,但這個物理寄存器可能與在指令中指定的不同。唯一的一個例外就是狀態(tài)寄存器psr,任何對psr的引用總是執(zhí)行指向物理psr。,.,(3)在內(nèi)聯(lián)匯編代碼中不能使用寄存器pc(r15)、lr(r14)和sp(r13),任何試圖使用這些寄存器的操作都會導致出現(xiàn)錯誤消息。,(4)鑒于上述情況,在內(nèi)聯(lián)匯編語句塊中最好使用c或c+變量作為操作數(shù)。,(5)雖然內(nèi)聯(lián)匯編代碼可以更改處理器模式,但更改處理器模式會禁止使用c操,.,作數(shù)或?qū)σ丫幾gc代碼的調(diào)用,直到將處理器模式恢復為原設(shè)置之后。,6.5.2 嵌入式匯編,嵌入式匯編程序是一個編寫在c程序外的單獨匯編
24、程序,該程序段可以像函數(shù)那樣被c程序調(diào)用。,.,與內(nèi)聯(lián)匯編不同,嵌入式匯編具有真實匯編的所有特性,數(shù)據(jù)交換符合atpcs標準,同時支持arm和thumb,所以它可以對目標處理器進行不受限制的低級訪問。但是不能直接引用c/c+的變量。,用_asm聲明的嵌入式匯編程序像c函數(shù)那樣可以有參數(shù)和返回值。定義一個嵌入式匯編函數(shù)的語法格式為:,.,_asm returntype functionname(parameter-list) 匯編程序段 ,returntype:函數(shù)返回值類型; functionname:函數(shù)名; parameter-list:函數(shù)參數(shù)列表。,嵌入式匯編在形式上看起來就像使用關(guān)鍵字_asm進行了聲明的函數(shù),如下所示:,.,_
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年技術(shù)轉(zhuǎn)讓合同技術(shù)內(nèi)容詳細描述
- 2024年度紡織品生產(chǎn)購銷合同
- 2024年摩托車零部件安裝協(xié)議
- DB4105T 198-2022 丁鱥池塘養(yǎng)殖技術(shù)規(guī)程
- 04版9國際旅游業(yè)務(wù)合作合同
- 2024年投資聯(lián)盟:合作伙伴協(xié)議樣本
- 2024年房地產(chǎn)項目公共設(shè)施配套建設(shè)合同
- 2024年度膩子產(chǎn)品出口代理合同
- 2024年新建工程項目砂石料運輸合同書
- 2024年店鋪租賃合同書
- 代運營合作服務(wù)協(xié)議
- 婚內(nèi)財產(chǎn)協(xié)議書(2024版)
- 有限空間作業(yè)應(yīng)急管理制度
- 2024全國普法知識考試題庫及答案
- 化工企業(yè)中試階段及試生產(chǎn)期間的產(chǎn)品能否對外銷售
- 籃球智慧樹知到期末考試答案章節(jié)答案2024年浙江大學
- 國開作業(yè)《公共關(guān)系學》實訓項目1:公關(guān)三要素分析(六選一)參考552
- 碳排放核算與報告要求 第XX部分:鉛冶煉企業(yè)
- 物業(yè)及物業(yè)管理:提升旅游景區(qū)品質(zhì)
- 財政收支業(yè)務(wù)管理制度
- 肺功能進修總結(jié)匯報
評論
0/150
提交評論