常用ARM及匯編指令_第1頁
常用ARM及匯編指令_第2頁
常用ARM及匯編指令_第3頁
常用ARM及匯編指令_第4頁
常用ARM及匯編指令_第5頁
已閱讀5頁,還剩16頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論