版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第5章ARM指令集和匯編語言程序本章主要介紹以下內容:ARM指令集的基本特點與Thumb指令集的區(qū)別與x86處理器的區(qū)別ARM指令格式ARM尋址方式ARM指令集分類詳解ARM匯編語言的指示符ARM匯編語言語句格式ARM匯編語言程序格式ARM匯編語句格式和程序格式進階ARM匯編語言程序舉例4/3/20241第5章ARM指令集和匯編語言程序本章主要介紹以下內容:4/本講主要參考文獻ARM公司英文資料:ADS_AssemblerGuide_B.pdfDDI0100E_ARM_ARM.pdf中文圖書《ARM體系結構與編程》,清華大學出版社《嵌入式系統基礎教程》,機械工業(yè)出版社4/3/20242本講主要參考文獻ARM公司英文資料:4/2/202425.4ARM匯編語言程序的指示符ARM匯編語言源程序中語句由指令、指示符和宏指令組成。在ARM中將directive稱做指示符ARM的指示符指令相當于x86的偽指令在ARM中pseudo-instruction被稱為偽指令ARM指令集中只有4條偽指令而宏指令則是通過指示符定義的。使用MACRO和MEND指示符4/3/202435.4ARM匯編語言程序的指示符ARM匯編語言源程序中語句5.4.1符號定義指示符符號定義(Symboldefinition)指示符用于定義ARM匯編程序中的變量,對變量進行賦值以及定義寄存器名稱。包括以下指示符:GBLA,GBLL及GBLS聲明全局變量;LCLA,LCLL及LCLS聲明局部變量;SETA,SETL及SETS給變量賦值;RLIST為通用寄存器列表定義名稱;CN為協處理器的寄存器定義名稱;CP為協處理器定義名稱;DN及SN為VFP的寄存器定義名稱;FN為FPA的浮點寄存器定義名稱。4/3/202445.4.1符號定義指示符符號定義(Symboldefin5.4.2數據定義指示符數據定義(Datadefinition)指示符包括以下的指示符:LTORG聲明一個數據緩沖池(literalpool)的開始;MAP定義一個結構化的內存表(storagemap)的首地址;FIELD定義結構化的內存表中的一個數據域(field);SPACE分配一塊內存單元,并用0初始化;DCB分配一段字節(jié)的內存單元,并用指定的數據初始化;DCD及DCDU分配一段字的內存單元,并用指定的數據初始化;DCDO分配一段字的內存單元,并將單元的內容初始化成該單元相對于靜態(tài)基值寄存器的偏移量。4/3/202455.4.2數據定義指示符數據定義(Datadefini數據定義指示符(續(xù))DCFD及DCFDU分配一段雙字的內存單元,并用雙精度的浮點數據初始化。DCFS及DCFSU分配一段字的內存單元,并用單精度的浮點數據初始化。DCI分配一段字節(jié)的內存單元,用指定的數據初始化,指定內存單元中存放的是代碼,而不是數據。DCQ及DCQU分配一段雙字的內存單元,并用64位的整數數據初始化。DCW及DCWU分配一段半字的內存單元,并用指定的數據初始化。DATA在代碼段中使用數據?,F已不再使用,僅用于保持向前兼容。4/3/20246數據定義指示符(續(xù))DCFD及DCFDU分配一段雙字的內5.4.3匯編控制指示符匯編控制(Assemblycontrol)指示符包括下面的指示符:IF,ELSE及ENDIF匯編或者不匯編一段源代碼WHILE及WEND條件重復匯編相同的一段源代碼MACRO及MEND標識宏定義開始與結束MEXIT用于從宏跳轉出去4/3/202475.4.3匯編控制指示符匯編控制(Assemblyco5.4.4信息報告指示符信息報告(Reporting)指示符包括下列指示符:ASSERT在匯編編譯器對匯編程序的第二趟掃描中,如果其中的ASSERTION中條件不成立,ASSERT偽操作將報告該錯誤信息。INFO支持第一二趟匯編掃描時報告診斷信息。OPTTTL及SUBT4/3/202485.4.4信息報告指示符信息報告(Reporting)指5.4.5其他指示符這些雜類的指示符包括:ALIGNAREACODE16及CODE32ENDENTRYEQUEXPORT或GLOBAL4/3/202495.4.5其他指示符這些雜類的指示符包括:4/2/202其他的指示符(續(xù))EXTERNGET或INCLUDEIMPORTINCBINKEEPNOFPREQUIREREQUIRE8及PRESERVE8RNROUT4/3/202410其他的指示符(續(xù))EXTERN4/2/2024105.4.5.1AREAAREA指示符用于定義一個代碼段或者數據段。語法格式AREAsectionname{,attr}{,attr}....其中:sectionname為所定義的代碼段或者數據段的名稱。如果該名稱是以數字開頭的,則該名稱必須用“|”括起來,如|1_datasec|。還有一些代碼段具有約定的名稱,如|.text|表示C語言編譯器產生的代碼段或者是與C語言庫相關的代碼段。Attr是該代碼段(或者程序段)的屬性。在AREA指示符中,各屬性間用逗號隔開。4/3/2024115.4.5.1AREAAREA指示符用于定義一個代碼段或AREA的屬性下面列舉主要的屬性:ALIGN=expression。默認的情況下,ELF的代碼段和數據段是4字節(jié)對齊的。Expression可以取0~31的數值,相應的對齊方式為(2expression)字節(jié)對齊。如expression=3時為8字節(jié)對齊。ASSOC=section。指定與本段相關的ELF段。任何時候連接section段也必須包括sectionname段。CODE定義代碼段。默認屬性為READONLY。COMDEF定義一個通用的段。該段可以包含代碼或者數據。在個源文件中,同名的COMDEF段必須相同。4/3/202412AREA的屬性下面列舉主要的屬性:4/2/202412AREA的屬性(續(xù))COMMON定義一個通用的段。該段不包含任何用戶代碼和數據,連接器將其初始化為0。各源文件中同名的COMMON段公用同樣的內存單元,連接器為起分配合適的尺寸。DATA
定義數據段。默認屬性為READWRITE。NOINIT指定本數據段僅僅保留了內存單元,而沒有將各初始值寫入內存單元,或者將個內存單元值初始化為0。READONLY指定本段為只讀,代碼段的默認屬性為READONLY。READWRITE指定本段為可讀可寫,數據段的默認屬性為READWRITE。4/3/202413AREA的屬性(續(xù))COMMON定義一個通用的段。該段不包AREA指示符舉例舉例下面的指示符定義了一個代碼段,代碼段的名稱為Mainpro,屬性為READONLY。AREAMainpro,CODE,READONLY;codesegment4/3/202414AREA指示符舉例舉例4/2/2024145.4.5.2EQUEQU指示符為數字常量、基于寄存器的值和程序中的標號(基于PC的值)定義一個字符名稱。*是EQU的同義詞。語法格式nameEQUexpr{,type}其中:expr為基于寄存器的地址值、程序中的標號、32位的地址常量或者32位的常量。name為EQU指示符為expr定義的字符名稱。type當expr為32位常量時,可以使用type指示expr表示的數據的類型。4/3/2024155.4.5.2EQUEQU指示符為數字常量、基于寄存器的EQU(續(xù))type有下面3種取值:CODE16CODE32DATA使用說明EQU指示符的作用類似于C語言中的#define,用于為一個常量定義字符名稱。示例abcdEQU2 ;定義abcd符號的值為2abcdEQUlabel+16 ;定義abcd符號的值(label+16)addr1EQU0xlC,CODE32 ;定義addr1符號值為 ;絕對地址值0xlC,而且該處為ARM指令。4/3/202416EQU(續(xù))type有下面3種取值:4/2/2024165.4.5.3ENTRYENTRY指示符指定程序的入口點語法格式ENTRY使用說明一個程序(可以包含多個源文件)中至少要有一個ENTRY(可以有多個ENTRY),但一個源文件中最多只能有一個ENTRY(可以沒有ENTRY)。示例AREAexample,CODE,READONLYENTRY;應用程序的入口點4/3/2024175.4.5.3ENTRYENTRY指示符指定程序的入口點5.4.5.4CODE16和CODE32CODE16指示符告訴匯編編譯器后面的指令序列為16位的Thumb指令。CODE32指示符告訴匯編編譯器后面的指令序列為32位的ARM指令。語法格式CODE16CODE32使用說明當匯編源程序中同時包含ARM指令和Thumb指令時,使用CODE16指示符告訴匯編編譯器后面的指令序列為16位的Thumb指令;使用CODE32指示符告訴匯編編譯器后面的指令序列為32位的ARM指令。但是,CODE16指示符和CODE32指示符只是告訴編譯器后面指令的類型,該指示符本身并不進行程序狀態(tài)的切換。4/3/2024185.4.5.4CODE16和CODE32CODE16指示CODE16/CODE32舉例 在下面的例子中,程序先在ARM狀態(tài)下執(zhí)行,然后通過BX指令切換到Thumb狀態(tài),并跳轉到相應的Thumb指令處執(zhí)行。在Thumb程序入口處用CODE16指示符標識下面的指令為Thumb指令。參看下面的指令段:
………………. AREAChangeState,CODE,READONLY CODE32 ;指示下面的指令為ARM指令 LDRr0,=start+1 BXr0 ;切換到Thumb,并跳轉到start處執(zhí)行 CODE16 ;指示下面的指令為Thumb指令start MOVr1,#104/3/202419CODE16/CODE32舉例 在下面的例子中,程序先在AR5.4.5.5ENDEND指示符告訴編譯器已經到了源程序結尾。語法格式:END使用說明:每一個匯編源程序都包含END指示符,以告訴本源程序的結束。示例: AREAexampleCODE,READONLY………………END………4/3/2024205.4.5.5ENDEND指示符告訴編譯器已經到了源程序5.4.5.6ALIGNALIGN指示符通過添加補丁字節(jié)使當前位置滿足一定的對齊方式。語法格式ALIGN{expr{,offset}}其中,expr為數字表達式,用于指定對齊方式??赡艿娜≈禐?的次冪,如1、2、4、8等。如果指示符中沒有指定expr,則當前位置對齊到下一個字邊界處。offset為數字表達式。當前位置對齊到下面形式的地址處:offset+n*expr。4/3/2024215.4.5.6ALIGNALIGN指示符通過添加補丁字節(jié)使ALIGN(續(xù)1)使用說明下面的情況中,需要特定的地址對齊方式:Thumb的宏指令ADR要求地址是字對齊的,而Thumb代碼中地址標號可能不是字對齊的。這時就要使用指示符ALIGN4使Thumb代碼中的地址標號字對齊。由于有些ARM處理器的CACHE采用了其他對齊方式,如16字節(jié)的對齊方式,這時使用ALIGN指示符指定合適的對齊方式可以充分發(fā)揮該CACHE的性能優(yōu)勢。LDRD及STRD指令要求內存單元是8字節(jié)對齊的。這樣在為這兩個指令分配的內存單元前要使用ALIGN8實現8字節(jié)對齊方式。地址標號通常自身沒有對齊要求。而在ARM代碼中要求地址標號是字對齊的,在Thumb代碼中要求字節(jié)對齊。這樣需要使用合適的ALIGN指示符來調整對齊方式。4/3/202422ALIGN(續(xù)1)使用說明4/2/2024225.4.5.7EXPORT及GLOBALEXPRORT聲明一個符號可以被其他文件引用。相當于聲明了一個全局變量。GLOBAL是EXPORT的同義詞。語法格式EXPORTsymbol{[WEAK]}其中,symbol為聲明的符號名稱,大小寫敏感。[WEAK]選項聲明其他的同名符號優(yōu)先于本符號被引用。使用說明使用EXPORT指示符聲明一個源文件中的符號,使得該符號可以被其他源文件引用。示例AREAExample,CODE,READONLYEXPORTDo_Add;函數名稱DoAdd可以被引用4/3/2024235.4.5.7EXPORT及GLOBALEXPRORT聲明5.4.5.8IMPORTIMPORT指示符告訴編譯器當前的符號不是在本源文件中定義的,而是在其他源文件中定義的,在本源文件中可能引用該符號,而且不論本源文件是否實際引用該符號,該符號都將被加入到本源文件的符號表中。語法格式IMPORTsymbol{[WEAK]}其中:symbol為聲明的符號的名稱。它是區(qū)分大小寫的。[WEAK]指定這個選項后,如果symbol在所有的源文件中都沒有被定義,編譯器也不會產生任何錯誤信息,同時編譯器也不會到當前沒有被INCLUDE進來的庫中去查找該符號。4/3/2024245.4.5.8IMPORTIMPORT指示符告訴編譯器當IMPORT(續(xù))使用說明使用IMPORT指示符聲明一個符號是在其他源文件中定義的。如果連接器在連接處理時不能解析該符號,而IMPORT指示符中沒有指定[WEAK]選項,則連接器將會報告錯誤。如果連接器在連接處理時不能解析該符號,而IMPORT指示符中指定了[WEAK]選項,則連接器將不會報告錯誤,而是進行下面的操作:<1>如果該符號被B或者BL指令引用,則該符號被設置成下一條指令的地址,該B或者BL指令相當于一條NOP指令。<2>其他情況下該符號被設置為0。4/3/202425IMPORT(續(xù))使用說明4/2/2024255.4.5.9EXTERNEXTERN指示符告訴編譯器當前的符號不是在本源文件中定義的,而是在其他源文件中定義的,在本源文件中可能引用該符號。如果本源文件沒有實際引用該符號,該符號都將不會被加入到本源文件的符號表中。語法格式EXTERNsymbol{[WEAK]}其中,symbol為聲明的符號的名稱。它是區(qū)分大小寫的。[WEAK]指定該選項后,如果symbol在所有的源文件中都沒有被定義,編譯器也不會產生任何錯誤信息,同時編譯器也不會到當前沒有被INCLUDE進來的庫中去查找該符號。4/3/2024265.4.5.9EXTERNEXTERN指示符告訴編譯器當前EXTERN(續(xù)1)使用說明使用EXTERN指示符聲明一個符號是在其他源文件中定義的。如果連接器在連接處理時不能解析該符號,而EXTERN指示符中沒有指定[WEAK]選項,則連接器將會報告錯誤。如果連接器在連接處理時不能解析該符號,而EXTERN指示符中指定了[WEAK]選項,則連接器將不會報告錯誤,而是進行下面的操作:<1>如果該符號被B或者BL指令引用,則該符號被設置成下一條指令的地址,該B或者BL指令相當于一條NOP指令。<2>其他情況下該符號被設置為0。4/3/202427EXTERN(續(xù)1)使用說明4/2/202427EXTERN(續(xù)2)示例下面的代碼測試是否連接了C++庫,并根據結果執(zhí)行不同的代碼AREAExample,CODE,READONLYEXTERN_CPP_INITIALIZE[WEAK] ;如果連接了c++庫則讀取;函數_CPP_INITIALIZE地址LDRr0,_CPP_INITIALIZECMPr0,#0 ;Testifzero.BEQnocplusplus;如果沒有連接C++庫,則跳轉到nocplusplus4/3/202428EXTERN(續(xù)2)示例4/2/2024285.4.5.10GET及INCLUDEGET指示符將一個源文件包含到當前源文件中,并將被包含的文件在其當前位置進行匯編處理。INCLUDE是GET的同義詞。語法格式GETfilename其中,filename為被包含的源文件的名稱。這里可以使用路徑信息。使用說明(1)通??梢栽谝粋€源文件中定義宏,用EQU定義常量的符號名稱,用MAP和FIELD定義結構化的數據類型,這樣的源文件類似于C語言中的.H文件。然后用GET指示符將這個源文件包含到它們的源文件中,類似于在C源程序的“include*.h”。4/3/2024295.4.5.10GET及INCLUDEGET指示符將一個源GET及INCLUDE(續(xù)1)使用說明(2)編譯器通常在當前目錄中查找被包含的源文件??梢允褂镁幾g選項-I添加其他的查找目錄。同時,被包含的源文件中也可以使用GET指示符,即GET指示符可以嵌套使用。如在源文件A中包含了源文件B,而在源文件B中包含了源文件C。編譯器在查找C源文件時將把源文件B所在的目錄作為當前目錄。GET指示符不能用來包含目標文件(二進制執(zhí)行文件)。包含目標文件需要使用INCBIN指示符。4/3/202430GET及INCLUDE(續(xù)1)使用說明(2)4/2/2024GET及INCLUDE(續(xù)2)示例AREAExample,CODE,READONLYGETfile1.s ;包含源文件file1.sGETc:\project\file2.s;包含源文件file2.s,可以包含路徑信息GETc:\programfiles\file3.s;包含源文件file3.s,路徑信息中可以包含空格4/3/202431GET及INCLUDE(續(xù)2)示例4/2/2024315.4.5.11INCBININCBIN指示符將一個文件包含到(INCLUDE)當前源文件中,被包含的文件不進行匯編處理。語法格式INCBINfilename其中,filename為被包含的文件的名稱。這里可以使用路徑信息。使用說明通??梢允褂肐NCBIN將一個執(zhí)行文件或者任意的數據包含到當前文件中。被包含的執(zhí)行文件或數據將被原封不動地放到當前文件中。編譯器從INCBIN指示符后面開始繼續(xù)處理。4/3/2024325.4.5.11INCBININCBIN指示符將一個文件包INCBIN(續(xù))使用說明編譯器通常在當前目錄中查找被包含的源文件。可以使用編譯選項-I添加其他的查找目錄。同時,被包含的源文件中也可以使用GET指示符,即GET指示符可以嵌套使用。如在源文件A中包含了源文件B,而在源文件B中包含了源文件C。編譯器在查找C源文件時將把源文件B所在的目錄作為當前目錄。這里所包含的文件名及路徑信息中都不能有空格。示例AREAExample,CODE,READONLYINCBINfile1.dat ;包含文件file1.datINCBINc:\project\file2.txt ;包含文件file2.txt4/3/202433INCBIN(續(xù))使用說明4/2/2024335.4.5.12NOFP使用NOFP指示符禁止源程序中包含浮點運算指令。語法格式NOFP使用說明當系統中沒有硬件或軟件仿真代碼支持浮點運算指令時,使用NOFP指示符禁止在源程序中使用浮點運算指令。這時如果源程序中包含浮點運算指令,編譯器將會報告錯誤。同樣如果在浮點運算指令的后面使用NOFP指示符,編譯器同樣將會報告錯誤。4/3/2024345.4.5.12NOFP使用NOFP指示符禁止源程序中包含5.4.5.13REQUIREREQUIRE指示符指定段之間的相互依賴關系。語法格式REQUIRElabel
其中,label為所需要的標號的名稱。使用說明當進行連接處理時包含了有REQUIRElabel指示符的源文件,則定義label的源文件也將被包含。4/3/2024355.4.5.13REQUIREREQUIRE指示符指定段之5.4.5.14RNRN指示符為一個特定的寄存器定義名稱。語法格式nameRNexpr其中:expr為某個寄存器的編碼。name為本指示符給寄存器expr定義的名稱。使用說明RN指示符用于給一個寄存器定義名稱。方便程序員記憶該寄存器的功能。4/3/2024365.4.5.14RNRN指示符為一個特定的寄存器定義名稱。5.5ARM匯編語言語句格式ARM匯編語言語句格式如下所示:{symbol}{instruction|directive|pseudo-instruction}{;comment}其中:instruction為指令。在ARM匯編語言中,指令不能從一行的行頭開始。在一行語句中,指令的前面必須有空格或者符號。Directive是指示符。pseudo-instruction是偽指令。4/3/2024375.5ARM匯編語言語句格式ARM匯編語言語句格式如下所示ARM匯編語言語句格式(續(xù))symbol為符號。在ARM匯編語言中,符號必須從一行的行頭開始,并且符號中不能包含空格。在指令和偽指令中符號用作地址標號(label);在有些指示符中,符號用作變量或者常量。comment為語句的注釋。在ARM匯編語言中注釋以分號“;”開頭。注釋的結尾即為一行的結尾。注釋也可以單獨占用一行。4/3/202438ARM匯編語言語句格式(續(xù))symbol為符號。在ARM匯編ARM匯編程序編寫規(guī)范匯編語句格式ARM匯編中,所有標號必須在一行的頂格書寫,其后面不要添加符號“:”。而所有指令均不能頂格書寫。ARM匯編器對標識符大小寫敏感(即區(qū)分大小寫字母),書寫標號及指令時字母大小寫要一致。在ARM匯編程序中,ARM指令、偽指令、寄存器名可以全部為大寫字母,也可以全部為小寫字母,但不要大小寫混合使用。源程序中,語句之間可以插入空行,以使得源代碼的可讀性更好。
4/3/202439ARM匯編程序編寫規(guī)范匯編語句格式4/2/202439ARM匯編程序編寫規(guī)范(續(xù))格式如下:[標號]<指令|條件|S><操作數>[;注釋]源程序中允許有空行。適當地插入空行,可以提高源程序的可讀性。如果單行代碼太長,可以使用字符“\”將其分行。“\”后不能有任何字符,包括空格和制表符等。對于變量的設置、常量的定義,其標識符必須在一行的頂格書寫。下面給出了匯編指令正確和錯誤的例子4/3/202440ARM匯編程序編寫規(guī)范(續(xù))格式如下:4/2/202440匯編指令正確的例子…Str1 SETS“MyString1.” ;設置字符串變量Str1Count RNR0 ;定義寄存器名CountUSR_STACK EQU64 ;定義常量
START LDRR0,=0x12345678;1235678H MOVR1,#0LOOP MOVR2,#1…4/3/202441匯編指令正確的例子…4/2/202441匯編指令錯誤的例子
DOBMOVR0,#1 ;標號DOB沒有頂格書寫ABC: MOVR1,#2 ;標號不允許用符號“:”修飾MOV R2,#3 ;命令不允許頂格書寫loop Mov R2,#3 ;指令中大小寫混合 B Loop ;無法跳轉到loop標號,大小寫 ;不一致4/3/202442匯編指令錯誤的例子DOBMOVR0,#1 5.6ARM匯編語言程序格式ARM匯編語言以段(section)為單位組織源文件。段是相對獨立的、具有特定名稱的、不可分割的指令或者數據序列。段又可以分為代碼段和數據段,代碼段存放執(zhí)行代碼,數據段存放代碼運行時需要用到的數據。一個ARM源程序至少需要一個代碼段,大的程序可以包含多個代碼段和數據段。4/3/2024435.6ARM匯編語言程序格式ARM匯編語言以段(sectiARM匯編源程序和映像文件ARM匯編語言源程序經過匯編處理后生成一個可執(zhí)行的映像文件(類似于Windows系統下的EXE文件)。該可執(zhí)行的映像文件通常包括下面3部分:一個或多個代碼段。代碼段通常是只讀的。零個或多個包含初始值的數據段。這些數據段通常是可讀寫的。零個或多個不包含初始值的數據段。這些數據段被初始化為0,通常是可讀寫的。連接器根據一定的規(guī)則將各個段安排到內存中的相應位置。源程序中段之間的相鄰關系與執(zhí)行的映像文件中段之間的相鄰關系并不一定相同。4/3/202444ARM匯編源程序和映像文件ARM匯編語言源程序經過匯編處理后ARM匯編源程序基本結構舉例源程序基本結構如下示出: AREAEXAMPLE1,CODE,READONLY ENTRYstart MOV r0,#10 MOV r1,#3 ADD r0,r0,r1 END4/3/202445ARM匯編源程序基本結構舉例源程序基本結構如下示出:4/2/案例ARM匯編源程序說明在ARM匯編語言源程序中,指示符AREA定義一個段。AREA指示符表示了一個段的開始,同時定義了這個段的名稱及相關屬性。在本例中定義了一個只讀的代碼段,其名稱為EXAMPLE1。ENTRY指示符標識了程序執(zhí)行的第一條指令。一個ARM程序中可以有多個ENTRY,至少要有一個ENTRY。初始化部分的代碼以及異常中斷處理程序中都包含了ENTRY。如果程序包含了C代碼,C語言庫文件的初始化部分也包含了ENTRY。本程序的程序體部分實現了一個簡單的加法運算。END指示符告訴匯編編譯器源文件結束。每一個匯編模塊必須包含一個END指示符,指示本模塊結束。4/3/202446案例ARM匯編源程序說明在ARM匯編語言源程序中,指示符AR匯編語言子程序調用在ARM匯編語言中,子程序調用是通過BL指令完成的。BL指令的語法格式如下:BLsubname其中,subname是調用的子程序的名稱。BL指令完成兩個操作:將子程序的返回地址放在LR寄存器中,同時將PC寄存器值設置成目標子程序的第一條指令地址。在子程序返回時可以通過將LR寄存器的值傳送到PC寄存器中來實現。子程序調用時通常使用寄存器R0~R3來傳遞參數和返回結果。4/3/202447匯編語言子程序調用在ARM匯編語言中,子程序調用是通過BL指匯編子程序調用舉例子程序DOADD完成加法運算,操作數放在R0和R1寄存器中,結果放在R0中。AREA EXAMPLE2,CODE,READONLY ENTRYstart MOVr0,#10 ;R0設置輸入參數 MOVr1,#3 ;R1設置輸入參數 BL doadd ;調用子程序doadddoadd ADDr0,r0,r1 ;子程序 MOV pc,lr ;從子程序中返回 END4/3/202448匯編子程序調用舉例子程序DOADD完成加法運算,操作數放在RARM匯編子程序的嵌套調用舉例-1這里給出的ARM匯編程序嵌套調用范例程序做如下計算:求自然數1到9的階乘的總和,半主機方式輸出運算結果如下圖所示。第3行顯示的是1~9的階乘,第2行顯示的是1!+2!+3!+4!+5!+6!+7!+8!+9!之總和。4/3/202449ARM匯編子程序的嵌套調用舉例-1這里給出的ARM匯編程序嵌ARM匯編子程序的嵌套調用舉例-2/*Thisprogramissemihostingoutputmode*//*Firstthemainfunctioncallassemblysummingsubprogram*//*Thenthesummingsubprogramcallassemblyfactorialsubprogram*/#include<stdio.h>externintasmFac(intn);structfactorial_sum{intcal_fn;intsum_fn;intfn[9];};externstructfactorial_sum*summing(structfactorial_sum*arg1);4/3/202450ARM匯編子程序的嵌套調用舉例-2/*ThisprogrARM匯編子程序的嵌套調用舉例-3intmain(void){ intj; structfactorial_sumfac={9,0,{1,1,1,1,1,1,1,1,1} };//設置參數 structfactorial_sum*result; //申請變量作為返回值 printf("ExampleofamultiAssemblyprogramcalling!\n"); result=summing(&fac); //調用求和函數R0存放的是FAC變量的首地址 printf("Thetotalsumis%d\n",result->sum_fn); //輸出結果 for(j=0;j<9;j++){ printf("%d\t",(result->fn)[j]); } }4/3/202451ARM匯編子程序的嵌套調用舉例-3intmain(voidARM匯編子程序的嵌套調用舉例-4;thedetailsofparameterstransfercomesfromATPCS;iftherearemorethan4args,stackwillbeusedEXPORTsummingIMPORTasmFac ;說明用到了其他文件中的子匯編程序AREASUMMING,CODE,READONLYsumming STMFD SP!,{R4-R5} ldr r1,[r0] ;r1=cal_fn mov r2,#1 ;將r2設置為當前需要計算的階乘數, ;它從1變化到cal_fn add r3,r0,#8 ;將r3指向fn數組 mov r5,#0 ;r5為總和,初始值置為0loop cmp r1,r2 ;將cal_fn與當前所需計算的階乘值比較 blt back ;如果小于,則返回4/3/202452ARM匯編子程序的嵌套調用舉例-4;thedetailsARM匯編子程序的嵌套調用舉例-5 STMFD SP!,{R0-R3,lr} ;保存ro~r3,lr ;因為調用了外部文件的匯編子程序 mov r0,r2 ;將r0設置為當前所需計算的階乘值 bl asmFac ;調用階乘函數 mov r4,r0 ;將返回值(階乘)存在r4中 ldmfd SP!,{R0
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 專利申請保密協議書(2篇)
- 學校食堂地磚鋪設合同
- 企業(yè)并購招投標代理合同樣本
- 共享工作空間租賃合同
- 酒店管理培訓學校聘用合同
- 高速公路泵車租賃合同模板
- 市政工程樁基施工合同樣本
- 展會模特禮儀聘用協議
- 玻璃廠三個人合資合同范例
- 品牌建設合作合同協議書3篇
- 旅游學概論最新復習題庫與答案
- Q∕SY 03026-2019 石腦油-行業(yè)標準
- 定向井及水平井基礎知識介紹
- 現行最新2014版江蘇省建筑與裝飾工程計價定額說明及計算規(guī)則
- 精神病??漆t(yī)院可行性研究報告.docx
- 水電站調速器系統最權威講義課件
- 仁愛英語九年級上冊詞匯全冊練習題(共17頁)
- 六年級上冊綜合實踐(食品安全)
- 膠合板生產工藝
- UML校園卡管理系統(共18頁)
- 干、濕球溫度與濕度對照表
評論
0/150
提交評論