版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
嵌入式LPC2103教程基于ARM的嵌入式程序設(shè)計(jì)第1頁(yè)/共223頁(yè)5.1ARM匯編語(yǔ)言的偽操作、宏指令與偽指令5.1.1兩種常見的ARM編譯開發(fā)環(huán)境5.1.2ADS編譯環(huán)境下的偽操作和宏指令5.1.3GNU編譯環(huán)境下的偽操作和宏指令5.1.4ARM匯編語(yǔ)言的偽指令第2頁(yè)/共223頁(yè)偽操作、宏指令與匯編程序有關(guān),不同編譯環(huán)境有不同形式和規(guī)則。偽操作:特殊指令助記符,在源程序匯編過程中由匯編程序處理,一旦匯編結(jié)束,使命結(jié)束。宏指令:由偽操作定義的一段獨(dú)立代碼,可插在源程序中。先定義,后使用,可互相調(diào)用,可遞歸調(diào)用。通過宏名調(diào)用,可設(shè)置輸入?yún)?shù);簡(jiǎn)化程序代碼,并不會(huì)節(jié)省程序空間。偽指令:特殊指令助記符,匯編時(shí)被合適機(jī)器指令代替成ARM或Thumb指令,實(shí)現(xiàn)真正的指令。第3頁(yè)/共223頁(yè)5.1.1兩種常見的ARM編譯開發(fā)環(huán)境ADS/SDTIDE開發(fā)環(huán)境:它由ARM公司開發(fā),使用CodeWarrior公司的編譯器;集成了GNU開發(fā)工具的IDE開發(fā)環(huán)境::它由GNU的匯編器as、交叉編譯器gcc、和鏈接器ld等組成。源代碼開放,對(duì)Linux支持。EmbestIDE英蓓特公司集成了GNU開發(fā)工具,并兼容SDT/ADS.第4頁(yè)/共223頁(yè)5.1.2ADS編譯環(huán)境下的偽操作和宏指令
ADS編譯環(huán)境下的偽操作可分為:符號(hào)定義(SymbolDefinition)偽操作數(shù)據(jù)定義(DataDefinition)偽操作匯編控制(AssemblyControl)偽操作信息報(bào)告(Reporting)偽操作其他(Miscellaneous)偽操作第5頁(yè)/共223頁(yè)符號(hào)定義偽操作偽操作語(yǔ)法格式作用GBLAGBLAVariable聲明一個(gè)全局的算術(shù)變量,初始化成0。GBLLGBLLVariable聲明一個(gè)全局邏輯變量,初始化{FALSE}。GBLSGBLSVariable聲明一個(gè)全局字符串變量,初始化空串“”。LCLALCLA
Variable聲明一個(gè)局部的算術(shù)變量,初始化成0。LCLLLCLLVariable聲明一個(gè)局部邏輯變量,初始化{FALSE}
。LCLSLCLSVariable聲明一個(gè)局部串變量,初始化成空串“”。SETAVariableSETAexpr給一個(gè)全局或局部算術(shù)變量賦值。SETLVariableSETLexpr給一個(gè)全局或局部邏輯變量賦值。SETSVariableSETSexpr給一個(gè)全局或局部字符串變量賦值。RLISTNameRLIST{listofregs}為一個(gè)通用寄存器列表定義名稱。CNnameCNexpr為一個(gè)協(xié)處理器的寄存器定義名稱。CPnameCPexpr為一個(gè)協(xié)處理器定義名稱。DN/SNnameDN/SNexpr為一個(gè)雙/單精度VFP寄存器定義名稱。FNnameFNexpr為一個(gè)FPA浮點(diǎn)寄存器定義名稱。第6頁(yè)/共223頁(yè)1)GBLA、GBLL、GBLS格式:GBLA/GBLL/GBLS 變量名說明:GBLA、GBLL、GBLS偽操作定義一個(gè)匯編程序中的全局變量,并初始化:GBLA定義一個(gè)全局?jǐn)?shù)字變量,初始化為0;GBLL定義一個(gè)全局邏輯變量,初始化為“F”;GBLS定義一全局字符串變量,初始化為空串;
全局變量,在整個(gè)程序范圍內(nèi)變量名必須唯一。
第7頁(yè)/共223頁(yè)2)LCLA、LCLL、LCLS格式:LCLA/LCLL/LCLS局部變量名說明:LCLA、LCLL、LCLS定義一個(gè)匯編程序的局部變量,一般只用于宏代碼,并初始化:LCLA定義一個(gè)局部的數(shù)字變量,初始化為0;LCLL定義一個(gè)局部的邏輯變量,初始化為F;LCLS定義一局部字符串變量,初始化為空串;聲明局部變量,在局部作用范圍內(nèi)變量名須唯一。第8頁(yè)/共223頁(yè)3)SETA、SETL、SETS格式:變量名SETA/SETL/SETS 表達(dá)式說明:SETA:給一個(gè)數(shù)字變量賦值;SETL:給一個(gè)邏輯變量賦值;SETS:給一個(gè)字符串變量賦值;格式中的變量名必須為已經(jīng)定義過的全局或局部變量,表達(dá)式為將要賦給變量的值。
第9頁(yè)/共223頁(yè)LCLAARIT;聲明一個(gè)局部的數(shù)字變量,變量名為ARITARITSETA0xAA;將該變量賦值為0xAALCLLloc ;聲明一個(gè)局部的邏輯變量,變量名為loc
loc
SETL{TRUE};將該變量賦值為真
GBLSst1;定義一個(gè)全局的字符串變量,變量名為st1
st1SETS“Testing”;將該變量賦值為“Testing”
使用示例第10頁(yè)/共223頁(yè)1)GBLAobjects;全局變量objects,為0objectsSETA0xff
;該變量賦值為0xffSPACEobjects;引用該變量2)MACRO;聲明一個(gè)宏$labelmessage$a;宏的原型LCLSerr;聲明一個(gè)局部變量err,空串errSETS“errorno:”
;向該變量賦值$label;代碼INFO0,err:CC::STR:$a;使用該串變量
MEND ;宏定義結(jié)束第11頁(yè)/共223頁(yè)4)RLIST格式:名稱RLIST{寄存器列表}說明:用于對(duì)一個(gè)通用寄存器列表定義名稱,該名稱可在ARM指令LDM/STM中使用。例:List RLIST{R0-R5,R8,R10}STMDFSP!,List第12頁(yè)/共223頁(yè)符號(hào)定義偽操作偽操作語(yǔ)法格式作用GBLAGBLAVariable聲明一個(gè)全局的算術(shù)變量,初始化成0。GBLLGBLLVariable聲明一個(gè)全局邏輯變量,初始化{FALSE}。GBLSGBLSVariable聲明一個(gè)全局字符串變量,初始化空串“”。LCLALCLA
Variable聲明一個(gè)局部的算術(shù)變量,初始化成0。LCLLLCLLVariable聲明一個(gè)局部邏輯變量,初始化{FALSE}。LCLSLCLSVariable聲明一個(gè)局部串變量,初始化成空串“”。SETAVariableSETAexpr給一個(gè)全局或局部算術(shù)變量賦值。SETLVariableSETLexpr給一個(gè)全局或局部邏輯變量賦值。SETSVariableSETSexpr給一個(gè)全局或局部字符串變量賦值。RLISTNameRLIST{listofregs}為一個(gè)通用寄存器列表定義名稱。CNnameCNexpr為一個(gè)協(xié)處理器的寄存器定義名稱。CPnameCPexpr為一個(gè)協(xié)處理器定義名稱。DN/SNnameDN/SNexpr為一個(gè)雙/單精度VFP寄存器定義名稱。FNnameFNexpr為一個(gè)FPA浮點(diǎn)寄存器定義名稱。第13頁(yè)/共223頁(yè)CN:為一個(gè)協(xié)處理器的寄存器定義名稱.0~15格式:nameCNexpr例:Powercn6CP:為一個(gè)協(xié)處理器定義名稱。0~15格式:nameCNexpr例:DZXcn6DN/SN:為一個(gè)雙/單精度VFP寄存器定義名稱。單精度VFP寄存器0~30;雙精度VFP寄存器0~15.nameDN/SNexpr例:heightDN6widthSN20第14頁(yè)/共223頁(yè)FN:為一個(gè)FPA浮點(diǎn)寄存器定義名稱。expr
0~7nameFNexprLengthFN6第15頁(yè)/共223頁(yè)數(shù)據(jù)定義偽操作
偽操作語(yǔ)法格式作用LTORGLTORG聲明一個(gè)數(shù)據(jù)緩沖池(文字池)的開始。MAPMAPexpr{,base-reg}定義結(jié)構(gòu)化內(nèi)存表(StorageMap)首地址。FIELD{label}FIELDexpr定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域。SPACE{label}SPACEexpr分配一塊連續(xù)內(nèi)存單元,并用0初始化。DCB{label}DCBexpr{,expr}分配一段字節(jié)內(nèi)存單元,并用expr初始化。DCD/DCDU{label}DCDexpr{,expr}分配一段字內(nèi)存單元。DCDO{label}DCDOexpr{…}分配一段字對(duì)齊的字內(nèi)存單元。DCFD/DCFDU{label}DCFD{U}fpliteral{,fpliteral}…為雙精度的浮點(diǎn)數(shù)分配字對(duì)齊的內(nèi)存單元。
DCFS/DCFSU{label}DCFS{U}fpliteral{,fpliteral}為單精度的浮點(diǎn)數(shù)分配字對(duì)齊的內(nèi)存單元。DCI{label}DCIexpr{,expr}…在ARM代碼中分配一段字對(duì)齊內(nèi)存單元;在Thumb代碼中,分配一段半字對(duì)齊半字內(nèi)存單元。DCQ/DCQU{label}DCQ{U}{﹣}literal{,{﹣}literal}…分配一段以雙字(8個(gè)字節(jié))為單位的內(nèi)存DCW/
DCWU{label}DCW{U}expr{,expr}…分配一段半字對(duì)齊的半字內(nèi)存單元。第16頁(yè)/共223頁(yè)1)LTORG
說明:聲明一個(gè)數(shù)據(jù)緩沖池(文字池)開始。暫放LDR數(shù)據(jù)可有多個(gè)。使用偽指令LDR時(shí),在子程序返回或無條件跳轉(zhuǎn)后,加入。
AREAExample,CODE,READONLYStartBLfunc1…func1LDRR1,=0X8000MOVPC,LR
LTORGDataSPACE40ENG第17頁(yè)/共223頁(yè)2)MAPMAPexpr{,base-register}
說明:定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址,“^”可以用來代替MAP。首地址為expr或expr+base-register。MAP與FIELD配合定義內(nèi)存表結(jié)構(gòu)。
MAPfun;fun為內(nèi)存表首地址;MAP0x100,R9;內(nèi)存表首地址為R9+0x100第18頁(yè)/共223頁(yè)3)
FILED{label}FIELDexpr
說明:定義內(nèi)存表各數(shù)據(jù)域字節(jié)長(zhǎng)度(不分配內(nèi)存單元),用于定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域,可用“#”
代替。expr表示所占字節(jié)數(shù);MAP和FIELD定義了數(shù)據(jù)結(jié)構(gòu),并不分配內(nèi)存單元;有三種形式:基于絕對(duì)地址的、基于相對(duì)地址的和基于PC的內(nèi)存表。第19頁(yè)/共223頁(yè)1.基于絕對(duì)地址的內(nèi)存表MAP8192constaFIELD4constbFIELD4xFIELD4yFIELD4stringFIELD16使用:LDRR0,constb;第20頁(yè)/共223頁(yè)2.基于相對(duì)地址的內(nèi)存表MAP0,R9constaFIELD4constbFIELD4xFIELD4yFIELD4stringFIELD16使用:ADRR9,FieldLDRR5,constb;LDRR5,[R9,#4]第21頁(yè)/共223頁(yè)3.基于PC的內(nèi)存表DataSPACE100MAPDataconstaFIELD4constbFIELD4xFIELD4yFIELD4stringFIELD16使用:LDRR5,constb;LDRR5,[PC,offset]第22頁(yè)/共223頁(yè)特殊內(nèi)存表:FIELD操作數(shù)為0,標(biāo)號(hào)表明當(dāng)前內(nèi)存單元地址。startEQU0x1000endEQU0x2000MAPstartconstaFIELD4constbFIELD4xFIELD4yFIELD4stringFIELD16endalertFIELD0ASSERTendalert<=endend;第2遍掃描時(shí),條件不成立,報(bào)告錯(cuò)誤第23頁(yè)/共223頁(yè)4)
SPACE
{label}SPACEexpr
說明:分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化為0,expr為要分配的字節(jié)數(shù),可用“%”代替。DataSPACE100;分配100個(gè)字節(jié)單元,初始化為0;第24頁(yè)/共223頁(yè)5)DCB{label}DCBexpr{,expr}說明:分配一塊字節(jié)單元并用expr進(jìn)行初始化。DCB可用“=”代替。expr為
-128~255
stringDCB“student”;73747564656E746)DCW/DCWU{label}DCW{U}expr{,expr}…說明:分配一段半字存儲(chǔ)單元并用expr初始化,DCW存儲(chǔ)空間是半字對(duì)齊的。expr為
-32768~65535;DataDCW-235,748,2446DCWnum+8第25頁(yè)/共223頁(yè)7)DCD/DCDU{label}DCDexpr{,expr}說明:分配一塊字存儲(chǔ)單元并用expr初始化,存儲(chǔ)空間是字對(duì)齊。DCD也可用“&”代替。DatalDCD1,5,10DatalDCDaddr+48)DCQ/DCQU{label}DCQ{U}{﹣}literal{,{﹣}literal}…說明:分配一塊以8個(gè)字節(jié)為單位存儲(chǔ)區(qū)域用literal初始化,存儲(chǔ)空間是字對(duì)齊的。DCQU功能跟DCQ類似,分配存儲(chǔ)單元不嚴(yán)格字對(duì)齊。第26頁(yè)/共223頁(yè)AREAMiscData,DATA,READWRITEData0DCQ-100,2_101Data1DCQU1000,-100000000DCQUnumber+4;number為數(shù)字表達(dá)式第27頁(yè)/共223頁(yè)9)DCFD/DCFDU{label}DCFD{U}fpliteral{,fpliteral}…說明:為雙精度浮點(diǎn)數(shù)分配一片連續(xù)字存儲(chǔ)單元并用fpliteral初始化,它定義的存儲(chǔ)空間是字對(duì)齊的,每個(gè)雙精度的浮點(diǎn)數(shù)占據(jù)兩個(gè)字單元。10)DCFS/DCFSU{label}DCFS{U}fpliteral{,fpliteral}說明:為單精度浮點(diǎn)數(shù)分配一片連續(xù)字存儲(chǔ)單元并用表達(dá)式初始化,它定義的存儲(chǔ)空間是字對(duì)齊的,每個(gè)單精度浮點(diǎn)數(shù)使用一個(gè)字單元。第28頁(yè)/共223頁(yè)DCFD1E308,-4E-100;每個(gè)兩個(gè)字單元,字對(duì)齊DCFDU10000,-0.1,3.1E26;字不對(duì)齊DCFS1E3,-4E-9;每個(gè)一個(gè)字單元,字對(duì)齊DCFSU1.0,-1,3.1E6;字不對(duì)齊第29頁(yè)/共223頁(yè)匯編控制偽操作偽操作語(yǔ)法格式作用IF,ELSE及ENDIFIFlogicalexpression…{ELSE…}ENDIF能夠根據(jù)條件把一段源代碼包括在匯編語(yǔ)言程序內(nèi)或者將其排除在程序之外。WHILE及WENDWHILElogicalexpression…WEND能夠根據(jù)條件重復(fù)匯編相同的一段源代碼。MACRO、MEND及MERITMACRO{$label}macroname{$parameter{,$parameter}…}…宏代碼MENDMACRO標(biāo)識(shí)宏定義的開始,MEND標(biāo)識(shí)宏定義的結(jié)束。MERIT用于從宏中跳轉(zhuǎn)出去。用MACRO和MEND定義的一段代碼,稱為宏定義體。通過宏名稱來調(diào)用宏。第30頁(yè)/共223頁(yè)
匯編控制偽指令I(lǐng)F、ELSE、ENDIFWHILE、WENDMACRO、MEND、MEXIT第31頁(yè)/共223頁(yè)1)IF、ELSE、ENDIFIFlogicalexpression…{ELSE…};可選ENDIF說明:IF、ELSE、ENDIF可以分別用“[”、“|”、“]”代替。IF、ELSE、ENDIF可以嵌套使用。第32頁(yè)/共223頁(yè)IFVariable=16BNESUB1LDRR0,=SUB0BXR0ELSEBNESUB0
…ENDIF第33頁(yè)/共223頁(yè)2)WHILE、WENDWHILElogicalexpression…WEND說明:根據(jù)邏輯表達(dá)式的成立與否決定是否循環(huán)執(zhí)行這個(gè)代碼段。WHILE、WEND偽指令可嵌套。countSETA1WHILEcount<=4countSETAcount+1…WEND第34頁(yè)/共223頁(yè)3)MACRO、MEND、MEXITMACRO{$label}macroname{$parameter{,$parameter}…}…宏代碼MEND說明:MACRO和MEND之間的代碼為宏定義體,在宏定義體的第一行聲明宏的原型,宏的原型包含宏名、所需的參數(shù)。在源程序被編譯時(shí),匯編器將宏調(diào)用展開,用宏定義中的指令序列替換程序中的宏調(diào)用,并將實(shí)際參數(shù)的值傳遞給宏定義中的參數(shù)。MERIT說明:用于從宏中退出。第35頁(yè)/共223頁(yè)例:(1)宏定義MACRO$labeljump$a1,$a2;宏名jump,參數(shù)a1,a2…$label.loop1…BGE$label.loop1BL$a1BGT$label.loop2…ADR$a2MEND第36頁(yè)/共223頁(yè)(2)宏調(diào)用examjumpsub,det(3)宏展開examloop1…BGEexamloop1examloop2BLsubBGTexamloop2…ADRR1,det第37頁(yè)/共223頁(yè)示例:在ARM中完成測(cè)試-跳轉(zhuǎn)操作需要兩條指令,定義一條宏指令完成測(cè)試-跳轉(zhuǎn)操作
MACRO
$label TestAndBranch $dest,$reg,$cc
$label CMP $reg, #0 B$cc $dest MEND第38頁(yè)/共223頁(yè);在程序中調(diào)用該宏testTestAndBranchNZero,r0,NE……NonZero;程序被匯編后,宏展開的結(jié)果
testCMPr0,#0 BNENZeroNZero第39頁(yè)/共223頁(yè)信息報(bào)告?zhèn)尾僮鱾尾僮髡Z(yǔ)法格式作用ASSERTASSERTlogicalexpression對(duì)匯編程序第二遍掃描,如果ASSERT條件不成立,將報(bào)告該錯(cuò)誤信息。INFOINFOnumeric-expression,string-expression在匯編處理第一遍掃描或者第二遍掃描時(shí)INFO報(bào)告診斷信息。OPTOPTn通過OPT偽操作可以在源程序中設(shè)置列表選項(xiàng)。TTLTTLtitle在列表文件的每一頁(yè)的開頭插入一個(gè)標(biāo)題。SUBTSUBTsubtitle在列表文件的每一頁(yè)的開頭插入一個(gè)子標(biāo)題。第40頁(yè)/共223頁(yè)1)ASSERTTop<>Tem;若相等,則報(bào)錯(cuò)誤類型且中止2)INFO0,”Version1.0”;第2遍掃描,報(bào)告
IFlabel1<=label2INFO4,”Dataoverrun”;第1遍掃描報(bào)錯(cuò)誤類型且中止
ENDIF3)OPT4;func前插入新的一頁(yè)
func4)TTLtitle5)SUBTsubtitle第41頁(yè)/共223頁(yè)其他偽操作偽操作語(yǔ)法格式作用CODE16CODE16告訴匯編編譯器后面指令序列為16位Thumb指令CODE32CODE32告訴匯編編譯器后面指令序列為32位ARM指令。EQUnameEQUexpr{,type}為數(shù)字常量、基于寄存器的值和程序中的標(biāo)號(hào)(基于PC的值)定義一個(gè)字符名稱。AREAAREAsectionname{,attr}{,attr}…定義一個(gè)代碼段或者數(shù)據(jù)段。ENTRYENTRY指定程序的入口點(diǎn)。ENDEND告訴編譯器已經(jīng)到了源程序結(jié)尾。ALIGNALIGN{expr{,offset}}通過添加補(bǔ)丁字節(jié)使當(dāng)前位置滿足一定對(duì)齊方式。EXPORT/GLOBALEXPORTsymbol{[WEAK]}聲明一個(gè)符號(hào)可被其他文件引用,聲明全局變量。IMPORTIMPORTsymbol{[WEAK]}告訴編譯器當(dāng)前符號(hào)不是在本源文件中定義的,而是在其他源文件中定義的,可能引用該符號(hào)。EXTERNEXTERNsymbol{[WEAK]}告訴編譯器當(dāng)前的符號(hào)不是在本源文件中定義而是在其他源文件中定義的,可能引用該符號(hào)。GET/INCLUDEGETfilename
將一個(gè)源文件包含到當(dāng)前源文件中,并將被包含的文件在其當(dāng)前位置進(jìn)行匯編處理。INCBININCBINfilename將一個(gè)文件包含到當(dāng)前源文件中,被包含的文件不進(jìn)行匯編處理。KEEPKEEP{symbol}告訴編譯器將局部符號(hào)包含在目標(biāo)文件符號(hào)表中。NOFPNOFP禁止源程序中包含浮點(diǎn)運(yùn)算指令。REQUIREREQUIRElable指定段之間的相互依賴關(guān)系。RNnameRNexpr為一個(gè)特定的寄存器定義名稱。ROUT{name}ROUT定義局部變量的有效范圍。第42頁(yè)/共223頁(yè)1)CODE16、CODE32說明:CODE16偽操作指示編譯器后面代碼為16位的Thumb指令。CODE32偽操作指示編譯器后面代碼為32位ARM指令。例子:AREAChangeState,CLDE,READONLYCODE32LDRR0,=start+1BXR0CODE16StartMOVR1,#10…第43頁(yè)/共223頁(yè)2)EQUnameEQUexpr{,type}
說明:用于將程序中的數(shù)字常量、標(biāo)號(hào)、基于寄存器的值賦予一個(gè)等效的名稱,類似于C語(yǔ)言中的#define,可用“*”代替EQU。如果表達(dá)式為32位的常量,可以指定表達(dá)式的數(shù)據(jù)類型,類型域可以有以下三種:CODE16/CODE32/DATAXEQU10YEQUlabel+100ZEQU0x10,CODE32regEQU0xE01FC080第44頁(yè)/共223頁(yè)3)AREAAREAsectionname{,attr}{,attr}…說明:定義一個(gè)代碼段、數(shù)據(jù)段或者特定屬性的段。如果段名以數(shù)字開頭,那么該段名需用“|”字符括起來,如|7wolf|,用C的編譯器產(chǎn)生的代碼一般也用“|”括起來。屬性表示該段相關(guān)屬性,多個(gè)屬性用,分隔。CODE代碼段;DATA數(shù)據(jù)段;READONLY只讀,代碼段默認(rèn);READWRITE可讀寫,數(shù)據(jù)段默認(rèn);ALIGN=expression.0~31,以2expression字節(jié)對(duì)齊。AREAChangeState,CLDE,READONLY第45頁(yè)/共223頁(yè)4)ENTRY說明:指定匯編程序的入口。一個(gè)程序可包含多個(gè)源文件,在一個(gè)源文件里最多只能有一個(gè)ENTRY或沒有ENTRY。在一個(gè)完整匯編程序中至少要有一個(gè)ENTRY,程序中也可以有多個(gè),此時(shí),程序的真正入口點(diǎn)可在鏈接時(shí)指定。AREAexampleCODE,READONLYENTRYCODE32STARTMOVR1,#0x53…END第46頁(yè)/共223頁(yè)5)END說明:每一個(gè)源程序包含一個(gè)END,表示結(jié)束。6)ALIGN添加補(bǔ)丁字節(jié)使當(dāng)前位置滿足一定對(duì)齊方式。
ALIGN{expr{,offset}}expr可能取值為2的n次冪,如1、2、4、8.默認(rèn)當(dāng)前位置對(duì)齊到下一個(gè)字邊界處。例如:AREAcache,CODE,ALIGN=3;8字節(jié)對(duì)齊…MOVPC,LR…ALIGN8第47頁(yè)/共223頁(yè)AREASCopy,CODE,READONLYENTRYMOVR1,#0xFF000000DCB0X11DCB0X34ALIGN4,3DCB0X24第48頁(yè)/共223頁(yè)7)EXPORT/GLOBALEXPORTsymbol{[WEAK]}說明:在程序中聲明一個(gè)符號(hào)(區(qū)分大小寫),其他文件中代碼可引用該符號(hào)。[,WEAK]聲明其他文件有同名的標(biāo)號(hào),則該同名標(biāo)號(hào)優(yōu)先于該標(biāo)號(hào)被引用。例如:AREAExample,CODE,READONLYEXPORTfunfunADDR0,R0,R1第49頁(yè)/共223頁(yè)8)IMPORTIMPORT符號(hào)[,WEAK]說明:告訴編譯器這個(gè)符號(hào)(區(qū)分大小寫)要在當(dāng)前源文件中使用,是在其他的源文件中定義的。[,WEAK]表示如果所有的源文件都沒有找到這個(gè)標(biāo)號(hào),編譯器也不會(huì)提示錯(cuò)誤信息。第50頁(yè)/共223頁(yè)9)EXTERNEXTERN符號(hào)[,WEAK]說明:告訴編譯器所使用的符號(hào)要在當(dāng)前源文件中引用,是在其他的源文件中定義的。與IMPORT不同的是,如果當(dāng)前源文件實(shí)際上沒有引用該符號(hào),該符號(hào)就不會(huì)被加入到當(dāng)前文件的符號(hào)表中。第51頁(yè)/共223頁(yè)10)GET/INCLUDEGET 文件名說明:將一個(gè)源文件包含到當(dāng)前的源文件、當(dāng)前位置展開進(jìn)行匯編處理。只能用于包含源文件,包含其他文件則需要使用INCBIN偽指令。11)INCBININCBIN文件名說明:將一個(gè)數(shù)據(jù)文件或者目標(biāo)文件包含到當(dāng)前的源文件中,編譯時(shí)被包含的文件不作任何變動(dòng)的存放在當(dāng)前文件中,編譯器從后面開始繼續(xù)處理。第52頁(yè)/共223頁(yè)AREAExample,CODE,READONLYGETfile.sGETc:\project\file2.sGETc:\windowsproject\file2.s;可有空格第53頁(yè)/共223頁(yè)12)RN
名稱 RN表達(dá)式說明:給一個(gè)寄存器定義一個(gè)別名,以便程序員記憶該寄存器的功能。COUNTRN6CHOOSERN9第54頁(yè)/共223頁(yè)13)ROUT[名稱]ROUT說明:給一個(gè)局部變量定義作用范圍。局部變量作用范圍為當(dāng)前ROUT和下一個(gè)ROUT之間。routineROUT;定義局部變量
…1routine;局部標(biāo)號(hào)1…BEQ%2routine…BGE%1routine2routine;局部標(biāo)號(hào)1…otherroutineROUT第55頁(yè)/共223頁(yè)5.1.3GNU編譯環(huán)境下偽操作和宏指令
GNU編譯環(huán)境下的偽操作可分為以下幾類:常量編譯控制偽操作匯編程序代碼控制偽操作宏及條件編譯控制偽操作其他偽操作第56頁(yè)/共223頁(yè)常量編譯控制偽操作偽操作語(yǔ)法格式作用.byte.byteexpr{,expr}…分配一段字節(jié)內(nèi)存單元,并用expr初始化。.hword/.short.hwordexpr{,expr}…分配一段半字內(nèi)存單元,并用expr初始化。.ascii.asciiexpr{,expr}…定義字符串expr(非零結(jié)束符)。.asciz/.string.ascizexpr{,expr}…定義字符串expr(以/0為結(jié)束符)。.float/.single.floatexpr{,expr}…定義一個(gè)32bitIEEE浮點(diǎn)數(shù)expr。.double.doubleexpr{,expr}…定義64bitIEEE浮點(diǎn)數(shù)expr。word/.long/.int.wordexpr{,expr}…分配一段字內(nèi)存單元,并用expr初始化。.fill.fillrepeat{,size}{,value}分配一段字節(jié)內(nèi)存單元,用size長(zhǎng)度value填充repeat次。.zero.zerosize分配一段字節(jié)內(nèi)存單元,并用0填充內(nèi)存。.space/.skip.spacesize{,value}分配一段內(nèi)存單元,用value將內(nèi)存單元初始化。第57頁(yè)/共223頁(yè)匯編程序代碼控制偽操作偽操作語(yǔ)法格式作用.section.sectionexpr定義域中包含的段。.text.text{subsection}將操作符開始的代碼編譯到代碼段或代碼段子段。.data.data{subsection}將操作符開始的數(shù)據(jù)編譯到數(shù)據(jù)段或數(shù)據(jù)段子段。.bss.bss{subsection}將變量存放到.bss段或.bss段的子段。.code16/.thumb.code16.thumb表明當(dāng)前匯編指令的指令集選擇Thumb指令集。.code32/.arm.code32.arm表明當(dāng)前匯編指令的指令集選擇ARM指令集。.end.end標(biāo)記匯編文件的結(jié)束行,即標(biāo)號(hào)后的代碼不作處理。.include.include“filename”將一個(gè)源文件包含到當(dāng)前源文件中。.align/.balign.align{alignment}{,fill}{,max}通過添加填充字節(jié)使當(dāng)前位置滿足一定的對(duì)齊方式。第58頁(yè)/共223頁(yè)宏及條件編譯控制偽操作偽操作語(yǔ)法格式作用.macro、.exitm及.endm.macroacroname{parameter{,
parameter}…}….endm.macro偽操作標(biāo)識(shí)宏定義的開始,.endm標(biāo)識(shí)宏定義的結(jié)束。用.macro及.endm定義一段代碼,稱為宏定義體。.exitm偽操作用于提前退出宏。.ifdef,.else及.endif.ifdefcondition….else….endif當(dāng)滿足某條件時(shí)對(duì)一組語(yǔ)句進(jìn)行編譯,而當(dāng)條件不滿足時(shí)則編譯另一組語(yǔ)句。其中else可以缺省。第59頁(yè)/共223頁(yè)其他偽操作偽操作語(yǔ)法格式作用.eject.eject在匯編符號(hào)列表文件中插入一分頁(yè)符。.list.list產(chǎn)生匯編列表(從.list到.nolist)。.nolist.nolist表示匯編列表結(jié)束處。.title.title“heading”使用“heading”作為標(biāo)題。.sbttl.sbttl“heading”使用“heading”作為子標(biāo)題。.ltorg.ltorg在當(dāng)前段的當(dāng)前地址(字對(duì)齊)產(chǎn)生一個(gè)文字池。.req.reqname,expr為一個(gè)特定的寄存器定義名稱。.err.err使編譯時(shí)產(chǎn)生錯(cuò)誤報(bào)告。.print.printstring打印信息到標(biāo)準(zhǔn)輸出。.fail.failexpr編譯匯編文件時(shí)產(chǎn)生警告。第60頁(yè)/共223頁(yè)5.1.4ARM匯編語(yǔ)言的偽指令
偽指令語(yǔ)法格式作用ADRADR{cond}
register,expr將基于PC或基于寄存器的地址值讀取到寄存器中。小范圍的地址讀取。ADRLADRL{cond}register,expr將基于PC或基于寄存器的地址值讀取到寄存器中。中等范圍的地址讀取。LDRLDR{cond}reg,=[expr|label-expr]將一個(gè)32位的立即數(shù)或者一個(gè)地址值讀取到寄存器中。大范圍的地址讀取。NOPNOP在匯編時(shí)將被替換成ARM中的空操作。第61頁(yè)/共223頁(yè)5.1.4ARM匯編語(yǔ)言的偽指令
匯編時(shí)被替換成ARM或Thumb指令
1)ADR{cond}
register,expr
expr:基于PC或寄存器的地址表達(dá)式,取值范圍:
地址非字對(duì)齊,-255~255
地址字對(duì)齊,-1020~1020
將基于PC或寄存器的地址值讀取到寄存器中。
ADR偽指令被替換成一條合適的指令(ADD指令或SUB指令)。如果不能用一條來實(shí)現(xiàn)ADR偽指令的功能,編譯器將報(bào)告錯(cuò)誤。
第62頁(yè)/共223頁(yè)ADR-小范圍的地址讀取偽指令示例:
start MOVr0,#10;PC=當(dāng)前指令地址+8字節(jié)
ADRr4,start
;本ADR偽指令將被編譯器替換成
;SUBr4,pc,#0xc第63頁(yè)/共223頁(yè)2)ADRL
ADRL{cond}
register,expr
將基于PC或基于寄存器的地址值expr讀取到寄存器中。被替換成2條ADD或SUBARM指令,中等范圍的地址讀取。
expr:基于PC或寄存器的地址表達(dá)式,取值:
地址非字對(duì)齊,-64KB~64KB
地址字對(duì)齊,-256KB~256KB
例如:
startMOVR0,#10
ADRR4,start+60000
第64頁(yè)/共223頁(yè)ADRL-中等范圍的地址讀取偽指令示例:
start MOVr0,#10;PC=當(dāng)前指令地址+8字節(jié)
ADRr4,start+60000
;本ADRL偽指令將被編譯器替換成兩條指令 ;ADDr4,pc,#0xe800
;ADDr4,r4,#0x254
;60000=0xEA60第65頁(yè)/共223頁(yè)3)LDR
LDR{cond}register,=[expr|label-expr]
expr:32位常數(shù)
①當(dāng)expr沒有超過MOV或MVN指令中地址取值范圍時(shí),編譯器用合適的MOV或MVN代替該LDR偽指令
②反之,編譯器將該常數(shù)放在數(shù)據(jù)緩沖池中,同時(shí)用一條基于PC的LDR指令讀取該常數(shù)。LDR偽指令處的PC值到數(shù)據(jù)緩沖池中目標(biāo)數(shù)據(jù)所在地址的偏移量要小于4KB。
label-expr為基于PC的地址表達(dá)式或外部表達(dá)式
編譯器將該數(shù)放在數(shù)據(jù)緩沖池中,同時(shí)用一條基于PC的LDR指令讀取該常數(shù);或鏈接生成;第66頁(yè)/共223頁(yè)示例1:將0xff0讀取到R1中
LDR R1,=0xFF0
;匯編后將得到MOVR1,#0xFF0示例2:將0xfff讀取到R1中
LDR R1,=0xFFF
;匯編后LDRR1,[PC,OFFSET_TO_LPOOL]
LTORG
;LPOOLDCD0xFFF示例3:將外部地址ADDR1讀取到R1中
LDR R1,=ADDR1
;匯編后LDRR1,[PC,OFFSET_TO_LPOOL]
;…
;LPOOLDCDADDR1 第67頁(yè)/共223頁(yè)4)NOP-空操作偽指令語(yǔ)法格式
NOP第68頁(yè)/共223頁(yè)5.2ARM匯編語(yǔ)言程序設(shè)計(jì)5.2.1ARM匯編中的文件格式5.2.2ARM匯編語(yǔ)言語(yǔ)句格式5.2.3ARM匯編語(yǔ)言編程的重點(diǎn)5.2.4ARM匯編程序?qū)嵗?9頁(yè)/共223頁(yè)5.2.1ARM匯編中的文件格式
ARM源程序文件(源文件)可由任意一種文本編輯器來編寫程序代碼,它一般為文本格式。在ARM程序設(shè)計(jì)中,常用的源文件分為以下幾種:源程序文件文件名說
明匯編程序文件*.S用ARM匯編語(yǔ)言編寫的ARM程序或Thumb程序。C程序文件*.C用C語(yǔ)言編寫的程序代碼。頭文件*.H為簡(jiǎn)化源程序,把常用到的常量命名、宏定義、數(shù)據(jù)結(jié)構(gòu)定義等等單獨(dú)放在頭文件。第70頁(yè)/共223頁(yè)5.2.2ARM匯編語(yǔ)言語(yǔ)句格式{symbol}{instruction|directive|pseudo-instruction}{;comment}其中:symbol為符號(hào)instruction為指令。directive為偽操作。pseudo-instruction為偽指令。comment為語(yǔ)句的注釋。第71頁(yè)/共223頁(yè)匯編語(yǔ)言的語(yǔ)句格式
ARM(Thumb)匯編語(yǔ)言的語(yǔ)句格式為:
{符號(hào)} {指令、偽操作或偽指令} {;注釋}符號(hào):從一行的行頭開始,不能包含空格,指令或偽指令中為地址標(biāo)號(hào),在偽操作中用作變量或常量。指令或偽指令:指令的前面必須有空格或符號(hào)注釋:以“;”開頭每一條指令的助記符可以全部大寫、或全部小寫,但不允許在一條指令中大、小寫混用。語(yǔ)句之間可以插入空行。如一條語(yǔ)句太長(zhǎng),可將該語(yǔ)句分為若干行來書寫,在行的末尾用“\”表示下一行與本行為同一條語(yǔ)句。第72頁(yè)/共223頁(yè)ARM匯編語(yǔ)言中的符號(hào)
代表地址(標(biāo)號(hào))、變量、常量。命名規(guī)則:
符號(hào)由大小寫字母、數(shù)字以及下劃線組成局部標(biāo)號(hào)以數(shù)字開頭(ROUT之間),其他不許符號(hào)是區(qū)分大小寫的;符號(hào)在其作用范圍內(nèi)必須唯一,不可同名;符號(hào)不能與系統(tǒng)內(nèi)部變量或預(yù)定義符號(hào)同名程序中的符號(hào)通常不要與指令助記符或者偽操作同名。當(dāng)同名時(shí),用雙豎線將符號(hào)括起來第73頁(yè)/共223頁(yè)1)數(shù)字常量
3種表示:十進(jìn)制、16進(jìn)制、n進(jìn)制16進(jìn)制:0x12345678n_xxx:8_654數(shù)字常量是32位的整數(shù) 無符號(hào)數(shù):0~232-1
有符號(hào)數(shù)時(shí):-231~231-1。EQU:定義數(shù)字常量第74頁(yè)/共223頁(yè)2)變量
變量有數(shù)字變量、邏輯變量和字符串變量數(shù)字變量的大小不應(yīng)超出數(shù)字變量所能表示范圍邏輯變量有兩種取值:真{true}或假{false}字符串變量的長(zhǎng)度不應(yīng)超出字符串變量所能表示的范圍GBLA、GBLL、GBLS:聲明全局變量LCLA、LCLL、LCLS:聲明局部變量SETA、SETL和SETS:賦值第75頁(yè)/共223頁(yè)3)標(biāo)號(hào)
表示程序中的指令或著數(shù)據(jù)地址的符號(hào)?;赑C的標(biāo)號(hào):位于目標(biāo)指令前或者程序中數(shù)據(jù)定義偽操作前的標(biāo)號(hào)。匯編時(shí)將被處理成PC值加上或減去一個(gè)數(shù)字常量。常用于表示跳轉(zhuǎn)指令的目標(biāo)地址,或代碼段少量數(shù)據(jù)?;诩拇嫫鞯臉?biāo)號(hào):用MAP,F(xiàn)IELD偽操作定義。匯編時(shí)將被處理成寄存器值加上或減去一個(gè)數(shù)字常量。用于訪問數(shù)據(jù)段數(shù)據(jù)。絕對(duì)地址:32位數(shù)字量:0~232-1第76頁(yè)/共223頁(yè)4)局部標(biāo)號(hào)
用于局部范圍代碼:當(dāng)前段或用ROUT定義范圍。定義語(yǔ)法:N{符號(hào)名}0~99+符號(hào)引用格式:%{F|B}{A|T}N{符號(hào)名}F:前向搜;B:后向搜;A:搜所用嵌套層;T:搜當(dāng)前層;第77頁(yè)/共223頁(yè)ROUT[名稱]ROUT說明:給一個(gè)局部變量定義作用范圍。局部變量作用范圍為當(dāng)前ROUT和下一個(gè)ROUT之間。routineROUT;定義局部變量
…1routine;局部標(biāo)號(hào)1…BEQ%2routine…BGE%1routine2routine;局部標(biāo)號(hào)1…otherroutineROUT第78頁(yè)/共223頁(yè)2.ARM匯編語(yǔ)言中的表達(dá)式
表達(dá)式由符號(hào)、數(shù)值、單目或多目操作符以及括號(hào)組成。在一個(gè)表達(dá)式內(nèi)各種元素的優(yōu)先級(jí):括號(hào)內(nèi)的表達(dá)式優(yōu)先級(jí)最高各種操作符有一定的優(yōu)先級(jí)相鄰的單目操作符的執(zhí)行順序?yàn)橛捎业阶螅瑔文坎僮鞣麅?yōu)先級(jí)高于其他操作符優(yōu)先級(jí)相同的雙目操作符執(zhí)行順序?yàn)橛勺蟮接业?9頁(yè)/共223頁(yè)1)字符串表達(dá)式
字符串: 雙引號(hào)“
”;$$->$;““->“
示例:
abcSETS“thisstringcontainsonly““doublequote”
defSETS“thisstringcontainsonly$$doublequote”第80頁(yè)/共223頁(yè)字符串表達(dá)式
操作符LEN:LEN:ACHR:CHR:ASTR:STR:ALEFTA:LEFT:BRIGHTA:RIGHT:BCCA:CC:B第81頁(yè)/共223頁(yè)LEN:LEN:A;返回字符串長(zhǎng)度GBLSSTRSTRSETS“AAA”:LEN:A:;LEN=3CHR:CHR:A;0~255ASCII整數(shù)轉(zhuǎn)換成串STR:STR:A;32位數(shù)字量轉(zhuǎn)為8個(gè)十六進(jìn)制串GLBAA1SETAA115:STR:A;將A1轉(zhuǎn)換成”0000000F”第82頁(yè)/共223頁(yè)LEFT:返回字符串左邊一定長(zhǎng)度字串
A:LEFT:BGBLSSTR1GBLSSTR2STR1SETS“AAABBB”STR2SETSSTR1:LEFT:3RIGHT:返回字符串右邊一定長(zhǎng)度字串A:RIGHT:BSTR1SETS“AAABBB”STR2SETSSTR1:RIGHT:
3CC:連接兩個(gè)字符串
A:CC:BSTR1SETS“AAACCC”STR2SETS“BBB”:CC:
(STR1:LEFT:3)第83頁(yè)/共223頁(yè)2)數(shù)字表達(dá)式:表示32位整數(shù)
由數(shù)字常量、數(shù)字變量、操作符和括號(hào)組成。無符號(hào)數(shù):0~232-1
有符號(hào)數(shù)時(shí):-231~231-1。
-n與-232-n整數(shù)數(shù)字量示例:a SETA 34906Addr DCD 0xA10E DCD 2_11001010c3 SETA 8_74007 DCQ 0x123456789abcdef第84頁(yè)/共223頁(yè)浮點(diǎn)數(shù)字量 單精度浮點(diǎn)數(shù)表示范圍:3.4e+38~1.18e-38
雙精度浮點(diǎn)數(shù)表示范圍:1.8e+308~2.23e-308示例:
DCFD 1E308,-4E100 DCFS 1.0 DCFD 3.725e15 DCFS 0x7FC00000 DCFD &FFF0000000000000第85頁(yè)/共223頁(yè)操作符NOT按位取反
:NOT:A+、-、×、/及MOD算術(shù)操作符A+B,A-B,A×B,A/B,A:MOD:BROL、ROR、SHL及SHR移位(循環(huán)移位)操作A:ROL:B,A:ROR:BA:SHL:B,A:SHR:B;GNU環(huán)境相當(dāng)于<<、>>.equx,0x00000001<<0x00000001;x=2AND、OR、EOR按位邏輯操作符A:AND:B,A:OR:B,A:EOR:B.equy,0x80000000>>0x00000001;y=230第86頁(yè)/共223頁(yè)4)邏輯表達(dá)式:取值為{FALSE}和{TRUE}
關(guān)系操作符:同類表達(dá)式(數(shù)字、字符串、基于寄存器、基于PC的表達(dá)式)的關(guān)系A(chǔ)=B A>BA<BA>=BA<=BA/=BA<>B第87頁(yè)/共223頁(yè)邏輯操作符:LNOT:A ;邏輯表達(dá)式A取反A:LAND:B;與A:LOR:B;或A:LEOR:B;異或第88頁(yè)/共223頁(yè)5)其他常用操作符
?操作符:返回代碼行所生成的可執(zhí)行代碼字節(jié)數(shù),例如:?X;返回符號(hào)X代碼行所生成可執(zhí)行代碼字節(jié)數(shù)。DEF操作符:判斷是否定義某個(gè)符號(hào),例如:
:DEF:X如果符號(hào)X已經(jīng)定義,則結(jié)果為真,否則為假。第89頁(yè)/共223頁(yè)3.ARM匯編語(yǔ)言程序格式以段section為單位來組織源文件的。段是相對(duì)獨(dú)立的、具有特定名稱的、不可分割的指令或者數(shù)據(jù)序列。分代碼段和數(shù)據(jù)段,代碼段存放執(zhí)行代碼,數(shù)據(jù)段存放代碼運(yùn)行時(shí)需要用到的數(shù)據(jù)。ARM源程序至少需要一個(gè)代碼段,大的程序可以包含多個(gè)代碼段和數(shù)據(jù)段。
第90頁(yè)/共223頁(yè)源程序匯編后生成一個(gè)可執(zhí)行的映像文件(ELF格式)
:包括3部分:一個(gè)代碼段;只讀0個(gè)或多個(gè)包含初始值的數(shù)據(jù)段??勺x寫;0個(gè)或多個(gè)不包含初始值的數(shù)據(jù)段。初始化為0;可讀寫;第91頁(yè)/共223頁(yè)一個(gè)簡(jiǎn)單的加法運(yùn)算舉例說明ARM匯編語(yǔ)言源程序的基本結(jié)構(gòu)
例如:一個(gè)簡(jiǎn)單的加法運(yùn)算
AREAEXAMPLE,CODE,READONLYENTRYstartMOVr0,#10MOVr1,#3ADDr0,r0,r1END第92頁(yè)/共223頁(yè)5.2.3ARM匯編語(yǔ)言編程的重點(diǎn)ARM數(shù)據(jù)處理操作設(shè)置條件碼匯編語(yǔ)言子程序調(diào)用及返回跳轉(zhuǎn)表思想ARM與Thumb之間的狀態(tài)轉(zhuǎn)換及函數(shù)的相調(diào)用第93頁(yè)/共223頁(yè)1.ARM數(shù)據(jù)處理操作ARM中數(shù)據(jù)的處理有以下三種形式:簡(jiǎn)單的寄存器操作立即數(shù)操作寄存器移位操作難點(diǎn):32位立即數(shù)在32位指令中的編碼ANDR8,R7,#&FFARM特有的寄存器移位操作ADDR3,R2,R1,LSL#3第94頁(yè)/共223頁(yè)2.設(shè)置條件碼ARM的任何數(shù)據(jù)處理指令都能通過增加“S”操作碼來設(shè)置條件碼(N,Z,C和V)。
條件執(zhí)行
ARM指令集不同尋常的特征是每條指令(除了某些v5T指令)都可以是條件執(zhí)行的。條件域cond占據(jù)32位指令域的高4位。28~31bit.
條件轉(zhuǎn)移
在程序中可以通過條件碼的使用讓微處理器決定是否進(jìn)行轉(zhuǎn)移,還可用來控制循環(huán)的退出。
第95頁(yè)/共223頁(yè)條件碼助記符后綴標(biāo)志含義0000EQZ置位相等0001NEZ清零不相等0010CS/HSC置位無符號(hào)數(shù)大于或等于0011CC/LOC清零無符號(hào)數(shù)小于0100MIN置位負(fù)數(shù)0101PLN清零正數(shù)或零0110VSV置位溢出0111VCV清零未溢出1000HIC置位Z清零無符號(hào)數(shù)大于1001LSC清零Z置位無符號(hào)數(shù)小于或等于1010GEN等于V帶符號(hào)數(shù)大于或等于1011LTN不等于V帶符號(hào)數(shù)小于1100GTZ清零且(N等于V)帶符號(hào)數(shù)大于1101LEZ置位或(N不等于V)帶符號(hào)數(shù)小于或等于1110AL忽略無條件執(zhí)行第96頁(yè)/共223頁(yè)例1:跳過語(yǔ)句簡(jiǎn)單,可用條件執(zhí)行代替轉(zhuǎn)移指令
CMPR0,#5BEQBYPASSADDR1,R1,R0SUBR1,R1,R2BYPASS:可替代為:
CMPR0,#5ADDNER1,R1,R0SUBNER1,R1,R2第97頁(yè)/共223頁(yè)例2:循環(huán)使用轉(zhuǎn)移指令:
MOVR0,#0LOOP…ADDR0,R0,#1CMPR0,#10
BNELOOP第98頁(yè)/共223頁(yè)3.匯編語(yǔ)言子程序調(diào)用及返回
子程序的調(diào)用ARM匯編語(yǔ)言中,子程序調(diào)用通過BL完成:
BLsubname;subname是被調(diào)用子程序名稱。將PC(R15)的值保存到LR寄存器(R14)中,PC被設(shè)置成目標(biāo)子程序第一條指令地址。子程序的返回在返回調(diào)用程序時(shí),轉(zhuǎn)移鏈接指令保存到LR寄存器(r14)中的值需要拷貝回程序寄存器PC(r15)。
第99頁(yè)/共223頁(yè)子程序返回的方法1)最簡(jiǎn)單子程序SUB2…MOVPC,R142)子程序中出現(xiàn)嵌套調(diào)用,鏈接寄存器LR壓入堆棧來進(jìn)行保存;SUB1STMFDR13!,{R0-R2,R14}BLSUB2…LDMFDR13!{R0-R2,PC}第100頁(yè)/共223頁(yè)例:子程序調(diào)用的方法AREAEXAMPLE,CODE,READONLYENTRYStartMOVR0,#10MOVR1,#3BLDoadd…DoaddADDR0,R0,R1MOVPC,LREND第101頁(yè)/共223頁(yè)4.跳轉(zhuǎn)表思想
由計(jì)算值確定調(diào)用一系列子程序中的一個(gè)。跳轉(zhuǎn)表是利用程序計(jì)數(shù)器PC在通用寄存器文件中的可見性實(shí)現(xiàn),下例所示:根據(jù)R0的值轉(zhuǎn)移到相應(yīng)子程序
BLJUMPTAB
…JUMPTABADRR1,SUBTABCMPR0,#SUBMAXLDRLSPC,[R1,R0,LSL#2]BERRORSUBTABDCDSUB0DCDSUB1DCDSUB2
第102頁(yè)/共223頁(yè)5.ARM與Thumb間的狀態(tài)轉(zhuǎn)換及函數(shù)的相調(diào)用Thumb不能獨(dú)立組成應(yīng)用系統(tǒng)1)狀態(tài)切換的實(shí)現(xiàn)
ARM/Thumb之間切換通過轉(zhuǎn)移指令BX實(shí)現(xiàn)。BX利用Rn中目的地址值的最后一位來判斷跳轉(zhuǎn)后的狀態(tài)。當(dāng)最后一位為0時(shí),表示轉(zhuǎn)移到ARM狀態(tài);當(dāng)最后一位為1時(shí),表示轉(zhuǎn)移到Thumb狀態(tài),如下圖所示。
第103頁(yè)/共223頁(yè)第104頁(yè)/共223頁(yè)CODE32ADRR0,Into_Thumb+1BXR0
…CODE16Into_Thumb+1
…
ADRR5,Back_to_ARMBXR5
…CODE32Back_to_ARM
第105頁(yè)/共223頁(yè)2)ARM與Thumb間的狀態(tài)轉(zhuǎn)換及函數(shù)的相調(diào)用同一狀態(tài)下在同一狀態(tài)下的子程序調(diào)用
BLfunction實(shí)現(xiàn)返回只需要從LR恢復(fù)PC:
MOVPC,LRARM/Thumb之間的函數(shù)調(diào)用:需要在BX之前先保存好LR,BX不能自動(dòng)保存返回地址到LR。需要由BX來切換狀態(tài),因?yàn)锽L不能完成狀態(tài)切換。需要
用“BXLR”來返回,不能使用“MOVPC,LR”,返回時(shí)要仔細(xì)考慮保存在LR中最低位的內(nèi)容是否正確。第106頁(yè)/共223頁(yè)5.2.4ARM匯編程序?qū)嵗?jiǎn)單的ARM指令程序數(shù)據(jù)塊復(fù)制利用跳轉(zhuǎn)表實(shí)現(xiàn)程序跳轉(zhuǎn)ADS編譯環(huán)境下的匯編代碼與GNU編譯環(huán)境下有較多不同點(diǎn),主要是符號(hào)及偽操作的不同。第107頁(yè)/共223頁(yè)第108頁(yè)/共223頁(yè)例90:簡(jiǎn)單的ARM指令程序
AREAARMex,CODE,READONLYENTRYstartMOVR0,#10MOVR1,#3ADDR0,R0,R1stopMOVR0,#&18LDRR1,=&20026SWI0x123456END第109頁(yè)/共223頁(yè)例90:數(shù)據(jù)塊復(fù)制
AREABlock,CODE,READONLYNUMEQU20ENTRYstartLDRR0,=srcLDRR1,=dstMOVR2,#NUMMOVSP,#&400BcopyMOVSR3,R2,LSR#3BEQCwordSTMFDSP!,{R4-R11}第110頁(yè)/共223頁(yè)OcopyLDMIAR0!,{R4-R11}STMIAR1!,{R4-R11}SUBSR3,R3,#1BNEOcopyLDMFDSP!,{R4-R11}CwordANDSR2,R2,#7BEQstopWcopyLDRR3,[R0],#4STRR3,[R1],#4SUBSR2,R2,#1BNEWcopy第111頁(yè)/共223頁(yè)stopMOVR0,#&18LDRR1,=&20026SWI0x123456AREABdata,DATA,READWRITEsrcDCD1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4dstDCD0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0END第112頁(yè)/共223頁(yè)例91:利用跳轉(zhuǎn)表實(shí)現(xiàn)程序的跳轉(zhuǎn)
AREAJump,CODE,READONLYNUMEQU2ENTRYStartMOVR0,#0MOVR1,#3MOVR2,#2BLFuncStopMOVR0,#&18LDRR1,=&20026SWI0x123456第113頁(yè)/共223頁(yè)FuncCMPR0,#NUMMOVHSPC,LRADRR3,JTableLDRPC,[R3,R0,LSL#2]JTableDCDDoAddDCDDoSubDoAddADDR0,R1,R2MOVPC,LRDoSubSUBR0,R1,R2MOVPC,LREND第114頁(yè)/共223頁(yè)5.3嵌入式C語(yǔ)言程序設(shè)計(jì)基礎(chǔ)5.3.1C語(yǔ)言“預(yù)處理偽指令”在嵌入式程序 設(shè)計(jì)中的應(yīng)用5.3.2嵌入式程序設(shè)計(jì)中的函數(shù)及函數(shù)庫(kù)5.3.3嵌入式程序設(shè)計(jì)中常用的C語(yǔ)言語(yǔ)句5.3.4嵌入式程序設(shè)計(jì)中C語(yǔ)言的變量、數(shù) 組、結(jié)構(gòu)、聯(lián)合符合C語(yǔ)言基本語(yǔ)法,面向嵌入式應(yīng)用
第115頁(yè)/共223頁(yè)5.3.1C語(yǔ)言“預(yù)處理偽指令”在嵌入式程序設(shè)計(jì)中的應(yīng)用“預(yù)處理命令”改進(jìn)程序設(shè)計(jì)的環(huán)境,提高編程效率,一般以#號(hào)打頭,分為以下三種:文件包含宏定義條件編譯第116頁(yè)/共223頁(yè)1.文件包含將頭文件包含到程序中;頭文件中定義的內(nèi)容包括符號(hào)常量、復(fù)合變量原型、用戶定義的變
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝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ù)覽,若沒有圖紙預(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年專用:煤倉(cāng)租賃合同
- 2024互聯(lián)網(wǎng)游戲開發(fā)公司與運(yùn)營(yíng)商分成協(xié)議
- 2024年度體育賽事LED計(jì)分屏采購(gòu)合同
- 公益日活動(dòng)小結(jié)(12篇)
- 2024年度EPS圍擋施工及拆除合同
- 2024天然氣運(yùn)輸環(huán)境影響評(píng)估協(xié)議
- 2024年度信息系統(tǒng)安全運(yùn)維合同-PKISSL基礎(chǔ)應(yīng)用
- 2024年度物流倉(cāng)儲(chǔ)服務(wù)合作協(xié)議
- 2024年家禽養(yǎng)殖數(shù)字化管理系統(tǒng)建設(shè)合同
- 2024年幼兒園共建協(xié)議
- 教育信息化教學(xué)資源建設(shè)規(guī)劃
- 上海市交大附中附屬嘉定德富中學(xué)2024-2025學(xué)年九年級(jí)上學(xué)期期中考數(shù)學(xué)卷
- 屠宰場(chǎng)食品安全管理制度
- 部編版(2024秋)語(yǔ)文一年級(jí)上冊(cè) 6 .影子課件
- 2024秋期國(guó)家開放大學(xué)??啤缎淌略V訟法學(xué)》一平臺(tái)在線形考(形考任務(wù)一至五)試題及答案
- 基于SICAS模型的區(qū)域農(nóng)產(chǎn)品品牌直播營(yíng)銷策略研究
- 病例討論英文
- 2024秋期國(guó)家開放大學(xué)??啤兑簤号c氣壓傳動(dòng)》一平臺(tái)在線形考(形考任務(wù)+實(shí)驗(yàn)報(bào)告)試題及答案
- 【課件】植物體的結(jié)構(gòu)層次課件-2024-2025學(xué)年人教版生物七年級(jí)上冊(cè)
- 24秋國(guó)家開放大學(xué)《0-3歲嬰幼兒的保育與教育》期末大作業(yè)參考答案
- 相對(duì)濕度計(jì)算公式
評(píng)論
0/150
提交評(píng)論