版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、用ARM指令及匯編包括2指令集介紹4ARM數(shù)據(jù)處理指令包括7ARM偽指令介紹9ARM匯編程序設(shè)計及一些格式要求說明13用ARM指令及匯編包括1、ARM處理器尋址方式2、指令集介紹3、偽指令4、ARM匯編程序設(shè)計5、C與匯編混合編程ARM處理器尋址方式1、寄存器尋址:操作數(shù)的值在寄存器中,指令中的地址碼字段指出的是寄存器編號,指令執(zhí)行時直接取出寄存器值操作MOV R1, R2 R2->R1SUB R0, R1,R2 ;R1-R2 ->
2、;R02、立即尋址:立即尋址指令中的操作碼字段后面的地址碼部分就是操作數(shù)本身,也就是說,數(shù)據(jù)就包含在指令當(dāng)中,取出指令就取出了可以立即使用的操作數(shù)SUBS R0,R0,#1 R0-1 -> R0MOV R0,#0xff00 ;0xff00 -> R0注:立即數(shù)要以"#"為前綴,表示16進(jìn)制數(shù)值時以"0x"表示3、寄存器偏移尋址:是ARM指令集特有的尋址方式,當(dāng)?shù)?操作數(shù)是寄存器偏移方式時,第2個寄存器操作數(shù)在與第1個
3、操作數(shù)結(jié)合之前選擇進(jìn)行移位操作MOV R0,R2,LSL #3 R2的值左移3位,結(jié)果存入R0,即R0 = R2 * 8ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相與操作,結(jié)果放入R1寄存器偏移尋址可采用的移位操作如下(1)、LSL(Logical Shift Left)邏輯左移,寄存器中字的低端空出補(bǔ)0(2)、LSR(Logical Shift Right)邏輯右移,寄存器中字的高端空出補(bǔ)0(3)、ASR(Arthmetic Shift Right)算術(shù)
4、右移,移位中保持符號位不變,即如果源操作數(shù)為正數(shù),字高端空出補(bǔ)0,否則補(bǔ)1(4)、ROR(Rotate Right)循環(huán)右移,由字的低端移出的位填入高端空出的位(5)、RRX(Rotate Right eXtended by 1 place),操作數(shù)右移一位,左側(cè)空位由CPSR的C填充4、寄存器間接尋址:寄存器間接尋址指令中的地址碼給出的是一個通用寄存器的編號,所需要的操作數(shù)保存在寄存器指定地址的存儲單元中,即寄存器為操作數(shù)的地址指針LDR R1,R2 將R2中的數(shù)值作為地址,取出此地址中的數(shù)據(jù)保存在R1中SWP R1,R1,R2 ;將R
5、2中的數(shù)值作為地址,取出此地址中的數(shù)值與R1中的值交換5、基址尋址:將基址寄存器的內(nèi)容與指令中給出的偏移量相加,形成操作數(shù)的有效地址,基址尋址用于訪問基址附近的存儲單元,常用于查表,數(shù)組操作,功能部件寄存器訪問等。LDR R2,R3,#0x0F 將R3的數(shù)值加0x0F作為地址,取出此地址的數(shù)值保存在R2中STR R1,R0,#-2 ;將R0中的數(shù)值減2作為地址,把R1中的內(nèi)容保存到此地址位置 6、多寄存器尋址:一次可以傳送幾個寄存器值,允許一條指令傳送16個寄存器的任何子集或所有
6、寄存器LDMIA R1!,R2-R7,R12 ;將R1所指向的地址的數(shù)據(jù)讀出到R2-R7,R12,R1自動更新STMIA R0!,R3-R6,R10 將R3-R6,R10中的數(shù)值保存到R0指向的地址,R0自動更新7、堆棧尋址:堆棧是特定順序進(jìn)行存取的存儲區(qū),堆棧尋址時隱含的使用一個專門的寄存器(堆棧指針),指向一塊存儲區(qū)域(堆棧),存儲器堆??煞譃閮煞N:向上生長:向高地址方向生長,稱為遞增堆棧向下生長:向低地址方向生長,稱為遞減堆棧如此可結(jié)合出四中情況:1、滿遞增:堆棧通過增大存儲器的地址向上增長,堆棧指針指向內(nèi)含有效數(shù)據(jù)項的最高地址,指令如 LDMFA,ST
7、MFA2、空遞增:堆棧通過增大存儲器的地址向上增長,堆棧指針指向堆棧上的第一個空位置,指令如 LDMEA,STMEA3、滿遞減:堆棧通過減小存儲器的地址向下增長,堆棧指針指向內(nèi)含有效數(shù)據(jù)項的最低地址,指令如 LDMFD,STMFD4、空遞減:堆棧通過減小存儲器的地址向下增長,堆棧指針指向堆棧下的第一個空位置,指令如 LDMED,STMEDSTMFD SP!,R1-R7,LR ;將R1-R7,LR入棧,滿遞減堆棧LDMFD SP!,R1-R7,LR ;數(shù)據(jù)出棧,放入R1-R7,LR寄存器,滿遞減堆棧8、塊拷貝尋址:多寄存器傳送指令用于一塊數(shù)據(jù)從存儲器的某一位置拷貝到另一位
8、置STMIA R0!,R1-R7 ;將R1-R7的數(shù)據(jù)保存到存儲器中,存儲器指針在保存第一個值之后增加,方向為向上增長STMIB R0!,R1-R7 ;將R1-R7的數(shù)據(jù)保存到存儲器中,存儲器指針在保存第一個值之前增加,方向為向上增長SIMDA R0!,R1-R7 ;將R1-R7的數(shù)據(jù)保存到存儲器中,存儲器指針在保存第一個值之后增加,方向為向下增長STMDB R0!,R1-R7 ;將R1-R7的數(shù)據(jù)保存到
9、存儲器中,存儲器指針在保存第一個值之前增加,方向為向下增長不論是向上還是向下遞增,存儲時高編號的寄存器放在高地址的內(nèi)存,出來時,高地址的內(nèi)容給編號高的寄存器9、相對尋址:是基址尋址的一種變通,由程序計數(shù)器PC提供基準(zhǔn)地址,指令中的地址碼字段作為偏移量,兩者相加后得到的地址即為操作數(shù)的有效地址BL ROUTE1 ;調(diào)用到 ROUTE1 子程序BEQ LOOP ;條件跳轉(zhuǎn)到 LOOP 標(biāo)號處 =指令集介紹指令格式:<opcode> <cond>S<Rd>,<Rn&
10、gt;,<operand2>其中<>內(nèi)的項是必須的,內(nèi)的項是可選的opcode 指令助記符,如 LDR,STR等cond 執(zhí)行條件,如 EQ,NE等S 是否影響CPSR寄存器的值,書寫時影響CPSR,否則不影響Rd 目標(biāo)寄存器Rn 第一個操作數(shù)的寄存器operand2 第二個
11、操作數(shù)指令格式舉例如下:LDR R0,R1 ;讀取R1地址上的存儲器單元內(nèi)容,執(zhí)行條件AL(無條件執(zhí)行)BEQ DATAEVEN 跳轉(zhuǎn)指令,執(zhí)行條件EQ,即相等跳轉(zhuǎn)到DATAEVENADDS R1,R1,#1 加法指令,R1+1 => R1 影響CPSR寄存器,帶有SSUBNES R1,R1,#0xD ;條件執(zhí)行減法運(yùn)算(NE),R1-0xD => R1,影響CPSR寄存器,帶有S條件碼表條件碼助記符標(biāo)志
12、含義EQZ=1相等NEZ=0不相等CS/HSC=1無符號數(shù)大于或等于CC/LOC=0無符號數(shù)小于MIN=1負(fù)數(shù)PLN=0正數(shù)VSV=1溢出VCV=0沒有溢出HIC=1,Z=0無符號數(shù)大于LSC=0,Z=1無符號數(shù)小于或等于GEN=V帶符號數(shù)大于或等于LTN!=V帶符號數(shù)小于GTZ=0,N=V帶符號數(shù)大于LEZ=1,N!=V帶符號數(shù)小于或等于AL 任何無條件執(zhí)行(指令默認(rèn)條件)條件碼應(yīng)用舉例:1、比較兩個值大小,C代碼如下:if(a>b) a+;else b+;寫出相應(yīng)的ARM指令代碼如下:設(shè)R0為a,R1為bCMP R0, R1 &
13、#160; R0與R1比較ADDHI R0,R0,#1 ; 若R0>R1,則R0=R0+1ADDLS R1,R1,#1 ; 若R0<=R1,則R1=R1+12、若兩個條件均成立,則將這兩個數(shù)值相加C代碼為: if(a!=10)&&(b!=20) a=a+b;對應(yīng)的ARM指令為:CMP R0,#10 ;比較R0是否為10CMPN
14、E R1,#20 ;若R0不為10,則比較R1是否為20ADDNE R0,R0,R1; 若R0不為10且R1不為20,則執(zhí)行 R0 = R0+R13、若兩個條件有一個成立,則將這兩個數(shù)值相加C代碼為: if(a!=10)|(b!=20) a=a+b;對應(yīng)的ARM指令為:CMP R0,#10 CMPEQ R1,#20 ADDNE R0,R0,R1ARM存儲訪問指令:LDR、STR、LDM、STM、SWPLDR/STR:加載/存儲字和無符號字節(jié)指令從尋址方式的地址計算方法分,加載/存儲指令有以下4
15、種形式:1,零偏移:LDR Rd,Rn2,前索引偏移: LDR Rd,Rn,#0x04!,LDR Rd,Rn,#-0x04 Rn不允許為R153,程序相對偏移:LDR Rd,label,label為程序標(biāo)號,該形式不能使用后綴!4,后索引偏移: LDR Rd,Rn,#0x04,Rn不允許是R15指令舉例如下:LDR R2,R5 ;加載R5指定地址上的數(shù)據(jù)(字),放入R2中STR R1,R0,#0x04 ;將R1的數(shù)據(jù)存儲到 R0+0x04存儲單元,R0的值不變 (若有!,則R0就要更新)LDRB R3,R2,#
16、1 ;讀取R2地址上的一字節(jié)數(shù)據(jù)并保存到R3中,R2=R2+1STRH R1,R0,#2! ;將R1的數(shù)據(jù)保存到R0+2的地址中,只存儲低2字節(jié)數(shù)據(jù),R0 =R0+2LDM和STM是批量加載/存儲指令,LDM為加載多個寄存器,STM為存儲多個寄存器,主要用途是現(xiàn)場保護(hù),數(shù)據(jù)復(fù)制、參數(shù)傳遞等,其模式有8種,前4種用于數(shù)據(jù)塊的傳輸,后4種用于堆棧操作 IA:每次傳送后地址加4IB:每次傳動前地址加4DA:每次傳送后地址減4DB:每次傳送前地址減4FD:滿遞減堆棧ED:空遞增堆棧FA:滿遞增堆棧EA:空遞增堆棧批量加載/存儲指令舉
17、例如下:LDMIA R0!,R3-R9 加載R0指向的地址上的多字?jǐn)?shù)據(jù),保存到R3-R9中,R0值更新STMIA R1!,R3-49 ;將R3-R9的數(shù)據(jù)存儲到R1指向的地址上,R1值更新STMFD SP!,R0-R7,LR 現(xiàn)場保存,將R0R7、LR入棧LDMFD SP!,R0-R7,PC ;恢復(fù)現(xiàn)場,異常處理返回使用LDM/STM進(jìn)行數(shù)據(jù)復(fù)制LDR R0,=SrcData ;設(shè)置源數(shù)據(jù)地址,LDR此時作為偽指令加載地址要加 =LDR R1,=Ds
18、tData ;設(shè)置目標(biāo)地址LDMIA R0,R2-R9 ;加載8字?jǐn)?shù)據(jù)到寄存器R2 R9STMIA R1,R2-R9 ;存儲寄存器R2-R9到目標(biāo)地址上使用LDM/STM進(jìn)行現(xiàn)場保護(hù),常用在子程序或異常處理中STMFD SP!,R0-R7,LR ;寄存器入棧.BL DELAY ;調(diào)用DELAY子程序.LDMFD SP!,R0-R7,PC 恢復(fù)寄存器,并返回SW
19、P是寄存器和存儲器交換指令,可使用SWP實現(xiàn)信號量操作12C_SEM EQU 0x40003000 ;EQU定義一個常量12C_SEM_WAIT 標(biāo)簽MOV R1,#0LDR R0,=12C_SEM SWP R1,R1,R0
20、0; 取出信號量,并設(shè)置為0CMP R1,#0 ;判斷是否有信號BEQ 12C_SEM_WAIT 若沒有信號,則等待ARM數(shù)據(jù)處理指令包括1、數(shù)據(jù)傳送指令2、算術(shù)邏輯運(yùn)算指令3、比較指令4、乘法指令A(yù)DC指令:帶進(jìn)位加法指令,將操作數(shù)2的數(shù)據(jù)與Rn的值相加,再加上CP
21、SR中C條件標(biāo)志位,結(jié)果保存到Rd中使用ADC指令實現(xiàn)64位加法ADDS R0,R0,R2 ; R0+R2 => R0,影響CPSR中的值A(chǔ)DC R1,R1,R3 ;(R1、R0) = (R1、R0)+(R3、R2)SBC指令:帶借位減法指令,用寄存器Rn減去操作數(shù)2,再減去CPSR中的C條件標(biāo)志位的非(即若C標(biāo)志清零,則結(jié)果減去1),結(jié)果保存在Rd中使用SBC實現(xiàn)64位減法SUBS R0,R0,R2SBC R1,R1,R3 ;使用SBC實現(xiàn)64位減法,(R1,R0) - (R3,R2)AND指令:按位與
22、操作ANDS R0,R0,#0x01 ;取出最低位數(shù)據(jù)ORR指令:按位或操作ORR R0,R0,#0x0F ;將R0的低4位置1EOR指令是進(jìn)行異或操作,BIC指令是位清除指令(遇1清0)TST:位測試指令TST R0,#0x01 ; 判斷R0的最低位是否是為0TEQ:相等測試指令TEQ R0,R1 比較R0與R1是否相等,也可看作相減,相等則為0,Z=1MUL指令:乘法指令MUL R1,R2,R3 ; R1=R2*R
23、3MULS R0,R3,R7 ; R0=R3*R7,同時設(shè)置CPSR中的N位和Z位MLA是乘加指令,將操作數(shù)1和操作數(shù)2相乘再加上第3個操作數(shù),結(jié)果的低32位存入到Rd中UMULL是64位無符號乘法指令UMULL R0,R1,R5,R8 ; (R1、R0) = R5 * R8BL指令:帶鏈接的跳轉(zhuǎn)指令,指令將下一條指令拷貝到R14(即LR)鏈接寄存器中,然后跳轉(zhuǎn)到指定地址運(yùn)行BL指令用于子程序調(diào)用,例如:BL DELAYBX指令:帶狀態(tài)切換的跳轉(zhuǎn)指令,例如 BX R0 ;跳轉(zhuǎn)到R0指定的地址,并根據(jù)R0的最低位來切換處理器的狀態(tài)MCR:ARM寄存器到協(xié)處理器
24、寄存器的數(shù)據(jù)傳送指令MRC:協(xié)處理器寄存器到ARM寄存器的數(shù)據(jù)傳送指令MRC/MCR指令格式如下:MRC/MCR cond coproc,opcode1,Rd,CRn,CRm,opcode2coproc是指令操作的協(xié)處理器名,標(biāo)準(zhǔn)名為pn,n為0-15opcode1 協(xié)處理器的特定操作碼Rd MRC操作時,作為目標(biāo)寄存器的協(xié)處理器寄存器,MCR操作時,作為ARM處理器的寄存器CRn 存放第1個操作數(shù)的協(xié)處理器寄存器CRm 存放第2個操作數(shù)的協(xié)處理器寄存器opcode2 可選的協(xié)處理器特定操作碼MRC/MCR指令舉例如下:mcr/mrc p15,0,r0,c1,c0,0SWI指令:S
25、WI指令用于產(chǎn)生中斷,從而實現(xiàn)用戶模式變換到管理模式,CPSR保存到管理模式的SPSR中,執(zhí)行轉(zhuǎn)移到SWI向量SWI 0x123456 ;軟中斷,中斷立即數(shù) 0x123456在SWI異常中斷處理程序中,取出SWI立即數(shù)的步驟為:首先確定引起軟中斷的SWI指令是ARM指令還是THUMB指令,這可通過對SPSR訪問得到,然后要取得該SWI指令的地址,這可通過訪問LR寄存器得到,接著讀出指令,分解出立即數(shù)程序代碼如下:T_bit EQU 0x20
26、 ;0010 0000SWI_Hander STMFD SP!,R0-R3,R12,LR ;現(xiàn)場保護(hù) MRS R0,SPSR ;讀取SPSR STMFD SP!,R0
27、160; 保存SPSR TST R0, #T_bit ;測試T標(biāo)志位,0為ARM,1為THUMB LDRNEH R0,LR,#-2 若是THUMB指令,讀出產(chǎn)生中斷的指令碼(16位) BICNE R0,R0,#0xFF00
28、 取得THUMB指令的8位立即數(shù) LDREQ R0,LR,#-4 ;若是ARM指令,讀取產(chǎn)生中斷的指令碼(32位) BICEQ R0,R0,#0xFF000000 ;取得ARM指令的24位立即數(shù) BL C_SWI_Handler L
29、DMFD SP!,R0-R3,R12,PC SWI異常中斷返回MRS指令:讀狀態(tài)寄存器指令,在ARM處理器中,只有MRS指令可以從狀態(tài)寄存器CPSR或SPSR讀出到通用寄存器MRS R1,CPSR ;將CPSR狀態(tài)寄存器讀取,保存到R1MRS R2,SPSR ;將SPSR狀態(tài)寄存器讀取,保存到R2MRS應(yīng)用:1、使能IRQ中斷ENABLE_IRQMRS R0,CPSRBIC R0,R0,#0x80 ;1000 0000
30、MSR CPSR,R0MOV PC,LR2、禁止IRQ中斷DISABLE_IRQMRS R0,CPSRORR R0,R0,#0x80MSR CPSR,R0MOV PC,LRMSR:寫狀態(tài)寄存器指令,在ARM處理器中,只有MSR指令可以直接設(shè)置狀態(tài)寄存器CPSR或SPSR=ARM偽指令介紹ARM偽指令不是ARM指令集中的指令,只是為了編程方便編譯器定義了偽指令A(yù)RM地址讀取偽指令有四條,分別是ADR 偽指令A(yù)DRL 偽指令LDR 偽指令NOP 偽指令作用的范圍不一樣,由小到大
31、: ADR,ADRL,LDRADR、ADRL指令將基于PC相對偏移的地址讀取到存儲器中,例如ADR R0 , DISP_TAB ; 加載轉(zhuǎn)換表地址LDR R1, R0,R2 ;使用R2作為參數(shù),進(jìn)行查表.DISP_TABDCB 0xc0,0xf9,0xa4,0x99,0x92,0x82,0xf8,0x80LDR偽指令用于加載32位的立即數(shù)或一個地址值到指定寄存器,前加 =LDR R0,=0x123456 ;加載32位
32、立即數(shù)0x123456LDR R0,=DATA_BUF+60 ;加載DATA_BUF地址+60NOP是空操作偽指令宏是一段獨(dú)立的程序代碼,它是通過偽指令定義的,在程序中使用宏指令即可調(diào)用宏,當(dāng)程序被匯編時,匯編程序?qū)γ總€調(diào)用進(jìn)行展開,用宏定義取代源程序中的宏指令符號定義偽指令1、全局變量聲明:GBLA、GBLL 和 GBLS2、局部變量聲明:LCLA、LCLL 和 LCLS3、變量賦值:SETA、SETL、和 SETS4、為一個通用寄存器列表定義名稱:RLIST5、為一個協(xié)處理器的寄存器定義名稱:CN6、為一個協(xié)處理器定義名稱:CP最后一個字符 A代表算術(shù)變量,初始值為0,L代表
33、邏輯變量,初值為FALSE,S代表字符串,初值為空偽指令應(yīng)用舉例如下:MACRO ;聲明一個宏SENDDAT $dat ;宏的原型 $表示后面是變量LCLA bitno 聲明一個局部算術(shù)變量.bitno SETA 8 &
34、#160; ;設(shè)置變量值為8.MEND ;結(jié)束RLIST指令格式:name RLIST reglist,例如: LoReg RLIST R0-R7 ;定義寄存器列表LoRegCN指令的用法:name CN expr,其中name是要定義的協(xié)處理器的寄存器名稱,expr對應(yīng)的協(xié)處理器的寄存器編號,數(shù)值范圍 0 15MemSet CN 1
35、 將協(xié)處理器的寄存器1名稱定義為 MemSetCP指令的用法,舉例如下:DivRun CP 5 將協(xié)處理器5名稱定義為DivRun數(shù)據(jù)定義偽指令:1、聲明一個文字池:LTORG2、定義一個結(jié)構(gòu)化的內(nèi)存表的首地址:MAP 或 3、定義結(jié)構(gòu)化內(nèi)存表中的一個數(shù)據(jù)域:FIELD 或 #4、分配一塊內(nèi)存空間,并用0初始化: SPACE 或 %5、分配一段字節(jié)內(nèi)存單元,并用指定的數(shù)據(jù)初始化: DCB6、分配一段字的內(nèi)存單元,并用指令的數(shù)據(jù)初始化: DCD 和 DCDU7、分配一段雙字的內(nèi)存單元,并用64位整數(shù)數(shù)據(jù)初始化: DCQ 和 DCQU8、分配一段半字的內(nèi)
36、存單元,并用指定的數(shù)據(jù)初始化: DCW 和 DCWULTORG 用于聲明一個文子池,在使用LDR偽指令時,要在適當(dāng)?shù)牡刂芳尤隠TORG聲明文子池,這樣就會把要加載的數(shù)據(jù)保存在文子池內(nèi),再用ARM的加載指令讀出數(shù)據(jù)(若沒有使用LTORG聲明文子池,則匯編器會在程序末尾自動聲明)LTORG偽指令應(yīng)用舉例如下:.LDR R0,=0x12345678ADD R1,R1,R0MOV PC,LRLTORG ;聲明文子池DCD 0x333DCD 0x555MAP 用于定義一個結(jié)構(gòu)化的內(nèi)存表的首地址,與MAP同義MA
37、P 0x00, R9 定義內(nèi)存表的首地址為R9FIELD 用于定義一個結(jié)構(gòu)化內(nèi)存表的數(shù)據(jù)域,#與FIELD同義 _ISR_STARTADDRESS ; is synonym for MAPHandleReset # 4 ; 定義數(shù)據(jù)域 HandleReset,長度為4字節(jié)SPACE用于分配一塊內(nèi)存單元,并用0初始化,%與SPACE同義偽指令應(yīng)用舉例如下:AREA DataRAM,DATA,READWROTE ;聲明一數(shù)據(jù)段,名為D
38、ataRAMDataBuf SPACE 1000 ;分配1000字節(jié)空間DCB偽指令格式:label DCB expr,expr .加的代表可有可無,DCD、DCW指令格式與DCB基本相同ASSERT為斷言錯誤偽指令,在匯編編譯器對匯編程序的第二遍掃描中,若其中ASSERT條件不成立,ASSERT偽指令將報告該錯誤信息ASSERT Top<>Temp ;斷言Top 不等于 TempASSERT :DEF:E
39、NDIAN_CHANGE 匯編控制偽指令1、條件匯編控制:IF、ELSE 和 ENDIFIF、ELSE 和 ENDIF 偽指令能夠根據(jù)條件把一段代碼包括在匯編程序內(nèi)或?qū)⑵渑懦诔绦蛑?與 IF同義 ,| 與 ELSE 同義, 與 ENDIF 同義偽指令應(yīng)用舉例如下: CONFIG = 16 ; 代表 IFBL _rt_udiv_1 | &
40、#160; ; | 代表 ELSEBL _rt_div0 ; 代表 ENDIF2、MACRO 和 MENDMACRO 和 MEND 偽指令用于宏定義,MACRO表示宏定義的開始,MEND表示宏定義的結(jié)束,用MACRO和MEND定義的一段代碼,稱為宏定義體,偽指令應(yīng)用如下:MACROCSI_SETB &
41、#160; ;宏名為CSI_SETB,無參數(shù)LDR R0,=rPDATG ;讀取GPG0 口的值LDR R1,R0ORR R1,R1,#0x01 CSI置位操作STR R1,R0 ;輸出控制MEND3、WHILE 和 WENDWHILE 和 WEND 偽指令用于根據(jù)條件重復(fù) 編相同的或幾乎相同的一段源程序偽指令應(yīng)用舉例WHILE no< 5no SETA no+1.WEND雜項偽指令:在匯編程序設(shè)計較為常用,如段定義偽指令,入口點(diǎn)設(shè)置偽指令,包含文件偽指令,標(biāo)號導(dǎo)出或引入聲明1、邊界對齊:ALI
42、GN2、段定義: AREA3、指令集定義:CODE16 和 CODE324、匯編結(jié)束: END5、程序入口: ENTRY6、常量定義:EQU7、聲明一個符號可以被其它文件引用:EXPORT 和 GLOBAL8、聲明一個外部符號:IMPORT 和 EXTERN9、包含文件: GET 和 INCLUDE10、給特定的寄存器命名: RNARM匯編程序設(shè)計及一些格式要求說明一般地,ARM源程序文件名的后綴名如下:匯編文件: *.S引入文件: *.INCC程序 : *.c頭文件 : *.h匯編語句格式: 標(biāo)號
43、; <指令 | 條件 | S > <操作數(shù)> ;注釋1、所有標(biāo)號必須在一行的頂格書寫,其后面不要加:2、所有指令均不能頂格書寫3、ARM匯編器對標(biāo)識符大小寫敏感,書寫標(biāo)號及指令時字母大小要一致,在ARM匯編程序中,一個ARM指令,偽指令,寄存器名可以全部為大寫字母,也可以全部為小寫字母,但不要大小寫混合使用4、注釋使用 ;或者 ,表示開始到此行結(jié)束,注釋可以在一行頂格書寫(對ADS匯編格式,只支持 ; )5、源程序中允許空行6、如果單行太長,可以使用字符 / 將其分行, / 后不能有任何字符,包括空格7、對于變量的設(shè)置,常
44、量的定義,其標(biāo)識符必須在一行的頂格書寫標(biāo)號:在ARM匯編中,標(biāo)號代表一個地址,根據(jù)標(biāo)號生成方式,可以分為以下3種1、基于PC的標(biāo)號,例如: BL LEDTEST2、基于寄存器的標(biāo)號,例如: MAP 0x00,R93、絕對地址,例如: LDR R0,=WTCON局部標(biāo)號:主要用于局部范圍代碼中,對宏定義也非常有用,格式如下:N routname N是局部標(biāo)號,為 0 99routname是局部標(biāo)號作用范圍的名稱局部標(biāo)號引用格式: % F | B A | T N routname 其中:% 表示局部標(biāo)號引用操作F 指示編譯器只向前搜索B 指示編譯器
45、只向后搜索A 指示編譯器搜索宏的所有嵌套層次T 指示編譯器搜索宏的當(dāng)前層應(yīng)用舉例如下: mov r1, #160 subs r1,r1, #1 bne %B0宏定義及其作用:使用宏定義可以提高程序的可讀性,簡化程序代碼和同步修改,宏首先要定義,然后再使用,當(dāng)源程序被匯編時,匯編器將展開每一個宏調(diào)用,用宏定義體代表程序中的宏調(diào)用,并使用
46、實際的參數(shù)值代替宏定義時的形式參數(shù)宏定義應(yīng)用舉例如下:.MACRO ;宏定義CALL $FUNCTION , $DAT1 , $DAT2 ;宏名稱為CALL,帶有3個參數(shù)IMPORT $FUNCTION ; 聲明外部子程序MOV R0, $DAT1 ; 設(shè)置子程序參數(shù),R0 = $DAT1MOV R1
47、, $DAT2 ;BL FUNCTION 調(diào)用子程序MEND ; 宏定義結(jié)束.匯編預(yù)處理后,宏調(diào)用將被展開,程序清單如下:.IMPORT FADD1MOV &
48、#160; R0, #3MOV R1, #3BL FADD1子程序的調(diào)用:使用BL指令進(jìn)行調(diào)用,該指令會把返回的PC值保存在LR示例如下: . BL DELAY .DELAY .
49、160; MOV PC,LR當(dāng)子程序指令完畢后,使用 MOV, B/BX , STMFD 等指令返回,STMFD 要與 LDMFD配套使用STMFD SP! , R0-R7, LR.LDMFD SP! , R0-R7,PC ARM7TDMI (-S) 是沒有BLX指令的,但可以通過以下幾條程序?qū)崿F(xiàn)其功能ADR R1 , DELAY+1MOV LR , PC ; 保存返回地址到LRBX
50、 R1 ; 跳轉(zhuǎn)并切換指令集.該程序要注意的是 3級流水線,PC執(zhí)行到哪里是關(guān)鍵特殊寄存器定義及應(yīng)用:基于ARM核的芯片一般有片內(nèi)外設(shè),它們通過其特殊寄存器訪問示例如下:WDTC EQU 0xE000000 ;寄存器定義
51、; . LDR R0, =WDTC ; 加載立即數(shù)要加 = MOV R1, #0x12
52、 STR R1, R0 WDTC = 0x12散轉(zhuǎn)功能是匯編程序常用的一種算法,其示例如下: CMP R0, #MAXINDEX
53、160; ; 判斷索引號是否超過最大索引值 ADDLO PC , PC , R0 , LSL #2 ; 若沒有超出,則跳轉(zhuǎn)到相應(yīng)位置 B ERROR
54、; ; 若已經(jīng)超出,則進(jìn)行出錯處理 ; 散轉(zhuǎn)表,對應(yīng)索引號為 0 N B FUN1 &
55、#160; B FUN2 B FUN3查表操作是匯編程序常用的一種操作,其示例如下: LDR R3, =DISP_TAB ;取得表頭
56、 LDR R2 , R3, R5, LSL #2 ;根據(jù)R5的值查表,取出相應(yīng)的值 . 下表為 0 - F 的自模DISR_TAB DCD 0xC0, 0xF9 , 0xA4 , 0x99 , 0x92 , 0xA1, 0xC6, 0x83
57、160; DCD 0x82. 0xF8 , 0x80 , 0x90 , 0x88 , 0x86, 0x8E , 0xFF長跳轉(zhuǎn)功能的實現(xiàn):ARM的B 和 BL 指令不能全空間跳轉(zhuǎn),但通過對PC進(jìn)行復(fù)制,實現(xiàn)32位地址的跳轉(zhuǎn)ADD LR , PC , #4 ;保存返回地址,即RET_FUNL
58、DR PC , PC , # -4 ; 跳轉(zhuǎn)到 LADR_FUNDCD LADR_FUNRET_FUN .也可以使用偽指令 LDR PC, =LADR_FUN 實現(xiàn)長跳轉(zhuǎn)匯編程序一個完整的例子:ABC EQU 0x12 AREA Example , CODE , READONLY ;聲明一個代碼段 Example
59、; ENTRY 入口處 CODE32 ADR R0, THUM
60、B_START + 1 ; 裝載地址,并設(shè)置第0位為1 BX R0
61、0; ; 切換到THUMB狀態(tài) CODE 16 &
62、#160; ; 聲明 16位代碼THUMB_START MOV R1, #ABC ADD
63、; R1, R1 , #0x10 B THUMB_START END外圍部件控制:在ARM核芯片中,其外圍部件的控制寄存器,一般會設(shè)置“置位/復(fù)位”寄存器,這樣可以方便的實現(xiàn)位操作,而不影響到其它位,操作示例如下:LDR R0 , =
64、GPIO_BASEMOV R1 , #0x00STR R1 , R0 , #0x04 MOV R1 , #0x10STR R1 , R0 , #0x0C =C與匯編混合編程在需要C與匯編混合編程時,可使用直接內(nèi)存匯編的方法混合編程,或者將匯編文件以文件的形式加入項目中內(nèi)嵌匯編的語法:_asm 指令 ;指令 /*注釋*/ .
65、0; 指令應(yīng)用舉例:_inline void enable_IRQ(void) int temp _asm /嵌入?yún)R編代碼
66、; MRS tmp , CPSR /讀取CPSR的值 BIC tmp , tmp, #0x80 /IRQ中斷禁止位I清零,即允許中斷 &
67、#160; MSR CPSR , tmp /設(shè)置CPSR的值 ARM編譯器特定的關(guān)鍵詞_asm:告訴編譯器下面的代碼是用匯編寫的_inline:聲明該函數(shù)在其被調(diào)用的地方展開_irq:聲明該函數(shù)可以被用做irq或者fiq異常的中斷處理程序_pure:聲明一個函數(shù),其結(jié)果僅僅依賴于其輸入?yún)?shù),而且它沒有負(fù)效應(yīng)_int64:是long long 的同義
68、詞_volatile:告訴編譯器該對象可能在程序之外被修改_weak:用于限定一個對象,該對象如果連接時不存在,不會報錯內(nèi)嵌匯編的指令用法:1、不能直接向PC寄存器賦值,程序跳轉(zhuǎn)只能使用 B 或 BL指令實現(xiàn),但是只有B可以使用C程序中的標(biāo)號,BL不能2、在內(nèi)嵌匯編指令中,常量前面的 # 可以省略3、所有的內(nèi)存分配均由C編譯器完成,內(nèi)嵌匯編器不支持內(nèi)嵌匯編程序用于內(nèi)存分配的偽指令以上的常見的注意事項內(nèi)嵌匯編器與 armasm 匯編器的差異1、內(nèi)嵌匯編器不支持通過 " . " 指示符 或 PC 獲取 當(dāng)前指令地址, 不支持 LDR Rn , =expr偽指令2、使用 Mov&
69、#160; Rn , expr 指令向寄存器賦值,不支持標(biāo)號表達(dá)式,不支持 ADR和ADRL,不支持BX,不能向PC賦值3、N、Z、C 和V標(biāo)志中的C不具有真實意義內(nèi)存匯編還有一些注意事項:1、不要使用寄存器代替變量,盡管有時候寄存器明顯對應(yīng)某個變量int had_f (int x) _asm ADD R0,R0, #1
70、 /發(fā)生寄存器沖突,實際上x的值沒有變化 return(x) ;使用 IMPORT 偽指令來引入全局變量,并利用LDR 和 STR 指令根據(jù)全局變量的地址訪問它們下面例子是一個匯編代碼的函數(shù),它讀取全局變量 glovbvar,將其加1后返回 AREA globats , CODE , READONLY
71、; EXPORT asmsubroutime IMPORT glovbvarasmsubroutime LDR R1, =glovbvar LDR R0, R1
72、; ADD R0 , R0 , #1 STR R0 , R1 MOV PC , LR ENDC與匯編相互調(diào)用寄存器的使用規(guī)則為:子程序間通過寄存器R0 - R3 來傳遞參數(shù),使用 R4 - R11來保存局部變量, R12用作過程調(diào)用中間臨時寄存器,記作 IP, R1
73、3用作堆棧指針,R14作為鏈接寄存器,記作 LR,R15是程序計數(shù)器子程序參數(shù)傳遞規(guī)則:當(dāng)寄存器不超過4個時,使用 R0 - R3來傳遞參數(shù),當(dāng)超過4個時,可以使用堆棧來傳遞參數(shù),入棧的順序與參數(shù)順序相反,即最后一個字?jǐn)?shù)據(jù)先入棧子程序結(jié)果返回規(guī)則:結(jié)果為一個32位的整數(shù)時,可以通過寄存器R0返回,如果是64位,通過R0和R1返回,對于位數(shù)更多的結(jié)果,需要通過內(nèi)存來傳遞 =C語言調(diào)用匯編程序:在匯編程序中使用 EXPORT 偽指令聲明本子程序,使其它程序可以調(diào)用子程序,在C語言程序中使用extern關(guān)鍵字聲明外部函數(shù)(聲明要調(diào)用的匯編子程序),即可調(diào)用此匯編子程序C程序調(diào)用匯編程序例子
74、如下:被調(diào)用的匯編子程序代碼: AREA SCopy , CODE , READONLY EXPORT strcopy ; 聲明strcopy ,以便外部程序引用strcopy ;R0 為目標(biāo)字符串的地址
75、 ; R1 為源字符串的地址 LDRB R2,R1 , #1 ; 讀取字節(jié)數(shù)據(jù),源地址加1 STRB R2,R0, #1 ; 保存讀取的1字節(jié)數(shù)據(jù),目標(biāo)地址加1 CMP R2, #0
76、 ; 判斷字符串是否復(fù)制完畢 BNE strcopy 沒有復(fù)制完畢,繼續(xù)循環(huán) MOV PC,LR ; 返回 E
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)銷售個人的工作總結(jié)
- 鄉(xiāng)村醫(yī)生先進(jìn)事跡500字(10篇)
- DB12T 598.17-2015 天津市建設(shè)項目用地控制指標(biāo) 第17部分:墓葬項目
- 中秋節(jié)的慰問信(5篇)
- 團(tuán)支部書記競選演講稿四篇
- 新學(xué)期學(xué)習(xí)計劃范本錦集8篇
- 業(yè)務(wù)員的實習(xí)報告范文4篇
- 高等數(shù)學(xué)教程 上冊 第4版 習(xí)題及答案 P177 第7章 多元微積分
- 天然氣公司股東協(xié)議書-企業(yè)管理
- 3D立體風(fēng)立體商務(wù)匯報
- 藍(lán)色簡約風(fēng)中國空軍成立75周年紀(jì)念日
- 2024年全國企業(yè)員工全面質(zhì)量管理知識競賽題庫(含答案)(共132題)
- 知識創(chuàng)業(yè)思維與方法智慧樹知到答案2024年湖南師范大學(xué)
- 無人機(jī)全行業(yè)保險
- 2023年廣東省建筑設(shè)計研究院校園招聘筆試參考題庫附帶答案詳解
- 員工人事檔案目錄
- 迅達(dá)SWE30-100K自動扶梯電路分析_圖文
- 電子工程師必備基礎(chǔ)知識
- 用戶運(yùn)營基礎(chǔ)知識
- 鈑金與焊接工藝規(guī)范
- 最新X線診斷報告模板(干貨分享)
評論
0/150
提交評論