嵌入式系統(tǒng)及應(yīng)用-Chapter06-匯編語(yǔ)言程序設(shè)計(jì)



單擊此處編輯母版標(biāo)題樣式,單擊此處編輯母版文本樣式,第二級(jí),第三級(jí),第四級(jí),第五級(jí),*,嵌入式系統(tǒng)及應(yīng)用,第六章,ARM,匯編語(yǔ)言程序設(shè)計(jì),ARM,偽指令,匯編程序設(shè)計(jì),ARM,偽指令,偽指令不像機(jī)器指令那樣在處理器運(yùn)行期間由機(jī)器執(zhí)行,而是在匯編時(shí)會(huì)被合適的機(jī)器指令代替,實(shí)現(xiàn)真正機(jī)器指令操作;,地址讀取偽指令,ADR,偽指令,小范圍的地址讀取偽指令,.ADR,指令將基于,PC,相對(duì)偏移的地址值讀取到寄存器中,.,在匯編編譯源程序時(shí),ADR,偽指令被編譯器替換成一條合適的指令,.,通常,編譯器用一條,ADD,指令或,SUB,指令來(lái)實(shí)現(xiàn)該,ADR,偽指令的功能;,指令格式:,ADRcond,register,exper,地址讀取偽指令,ADRL,偽指令,中等范圍的地址讀取偽指令,.ADRL,指令將基于,PC,相對(duì)偏移的地址值或基于寄存器 相對(duì)偏移的地址值讀取到寄存器中,比,ADR,偽指令可以讀取更大范圍的地址在匯編編譯源程序時(shí),,ADRL,偽指令被編譯器替換成兩個(gè)條合適的指令指令格式,ADRLcond,register,exper,地址讀取偽指令,LDR,偽指令,大范圍的地址讀取偽指令,.LDR,偽指令用于加載,32,位的立即數(shù)或一個(gè)地址值到指定 寄存器,.,指令格式,LDRcondregister,=,expr/label_expr,舉例,LDR R0,=0 x123456LDR R0,=DATA_BUFFER+0 x10.LTORG,NOP,偽指令,空操作偽指令,無(wú)操作,用于實(shí)現(xiàn)延時(shí);,舉例,DELAY1NOP,NOP,NOP,SUBS R1,R1,#1BNE DELAY1,變量定義偽指令,全局變量聲明,GBLA variable,:全局?jǐn)?shù)值變量,GBLL variable,:全局邏輯變量,GBLS variable,:全局字符串變量,局部變量聲明,LBLA variable,:局部數(shù)值變量,LBLL variable,:局部邏輯變量,LBLS variable,:局部字符串變量,變量賦值偽指令,給變量復(fù)制:,SETA,偽指令用于給一個(gè)全局,/,局部的算術(shù)變量賦值,.,SETL,偽指令用于給一個(gè)全局,/,局部的邏輯變量賦值,.,SETS,偽指令用于給一個(gè)全局,/,局部的字符串變量賦值,.,變量定義,/,賦值偽指令舉例,GBLL,CodeDbg,CodeDbg,SETL TRUE.GBLA,ByteNo,ByteNo,SETA 8.GBLS,ErrStr,ErrStr,SETS No,semaphone,.,RLIST,偽指令,RLIST,為一個(gè)通用寄存器列表定義名稱:,name RLIST,reglist,舉例:,LoReg,RLIST R0-R7,數(shù)據(jù)定義偽指令,數(shù)據(jù)定義偽指令用于數(shù)據(jù)表定義,文字池定義,數(shù)據(jù)空間分配等:聲明一個(gè)文字池:,LTORG,分配一塊內(nèi)存空間,并用,0,初始化,:SPACE,分配一段字節(jié)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化:,DCB,分配一段字的內(nèi)存單元,并用指令的數(shù)據(jù)初始化:,DCD,和,DCDU,LTORG,偽指令,LTORG,用于聲明一個(gè)文字池,(literal-pool),在使用,LDR,偽指令時(shí),要在適當(dāng)?shù)牡刂芳尤?LTORG,聲明 文字池,這樣就會(huì)把要加載的數(shù)據(jù)保存在文字池內(nèi),再用,ARM,的加載指令讀出數(shù)據(jù):,LTORG,舉例:,LDR R0,=0 x12345678ADD R1,R1,R0MOV PC,LRLTORG,SPACE,偽指令,SPACE,用于分配一塊內(nèi)存單元,并用,0,初始化,.%,與,SPACE,同義:,label SPACE,expr,舉例:,DataBuf,SPACE 1000;,分配,1000,字節(jié),DCB,偽指令,DCB,用于分配一段字節(jié)內(nèi)存單元,并用偽指令中的,expr,初始化,.,一般可用來(lái)定義數(shù) 據(jù)表格,或文字符串,.=,與,DCB,同義:,label DCB,expr,expr,expr,.,舉例:,DISPTAB DCB 0 x33,0 x43,0 x53DCB 0 x10,0 x20,0 x30ERRSTR DCB Send data error.,0,DCD,偽指令,DCD,用于分配一段字內(nèi)存單元,并用偽指令中的,expr,初始化,.&,與,DCD,同義:,label DCD,expr,expr,expr,舉例:,VectorsLDR,PC,ResetAddr,LDR,PC,UndefinedAddr,ResetAddr,DCDReset,UndefinedAddr,DCD UndefinedReset.,匯編控制偽指令,匯編控制偽指令用于條件匯編,宏定義,重復(fù)匯編控制等:條件匯編控制,:IF,ELSE,和,ENDIF,宏定義,:MACRO,和,MEND,重復(fù)匯編,:WHILE,及,WEND,IF,、,ELSE,和,ENDIF,偽指令,IF,ELSE,和,ENDIF,偽指令能夠根據(jù)條件把一段代碼包括在匯編程序內(nèi)或?qū)⑵渑懦?在程序之外:,IF,logical_expr,.ELSE.ENDIF,MACRO,和,MEND,偽指令,MACRO,和,MEND,偽指令用于宏定義,.MACRO,標(biāo)識(shí)宏定義的開(kāi)始,MEND,標(biāo)識(shí)宏定義久的 結(jié)束,.,用,MACRO,及,MEND,定義的一段代碼,稱為宏定義體:,MACRO$label,macroname,para1para2;,宏體定義,MEND,MACRO,和,MEND,偽指令,舉例:,MCARO$,IRQ_Label,HANDLER$,IRQ_Exception,EXPORT$,IRQ_Lable,IMPORT$,IRQ_Exception,$,IRQ_Lable,SUB LR,LR,#4STMFD SP!,R0-R3,R12,LRMRS R3,STSRSTMFD SP!,R3.MEND,DCD,偽指令,WHILE,和,WEND,偽指令用于根據(jù)條件重復(fù)匯編相同的或幾乎相同的一段源程序:,WHILE,logical_expr,WEND,舉例:,WHILE no 5no SETA no+1.WEND,雜項(xiàng)偽指令,邊界對(duì)齊,:ALIGN,段定義,:AREA,指令集定義,:CODE16,和,CODE32,匯編結(jié)束,:END,程序入口,:ENTRY,常量定義,:EQU,聲明符號(hào)可以被外部引用,:EXPORT,和,GLORBAL,聲明一個(gè)外部符號(hào),:IMPORT,和,EXTERN,包含文件,:GET,和,INCLUDE,包含不被匯編的文件,:INCBIN,ALIGN,偽指令,ALIGN,偽指令通過(guò)添加補(bǔ)丁字節(jié)使當(dāng)前位置滿足一定的對(duì)齊方式:,ALIGN,expr,舉例:,.,ByteBuf,DCB0 x10ALIGN 4.,AREA,偽指令,AREA,偽指令用于定義一個(gè)代碼段或數(shù)據(jù)段,.ARM,匯編程序設(shè)計(jì)采用分段式設(shè)計(jì),一 個(gè),ARM,源程序至少需要一個(gè)代碼段,大的程序可以包含多少個(gè)代碼段及數(shù)據(jù)段:,AREA,sectionname,attr,attr,舉例:,AREA,Example,CODE,READNOLY,AREA,偽指令,ALIGN:,定義對(duì)齊方式,CODE,:定義代碼段,COMDEF,:定義一個(gè)可包含代碼和數(shù)據(jù)的通用段,COMMON,:定義一個(gè)通用的段,DATA,:定義數(shù)據(jù)段,NOINIT,:無(wú)需初始化,READONLY,:指定本段為只讀,代碼段的默認(rèn)屬性為,READONLY,;,READWRITE,:指定本段為可讀可寫(xiě),.,數(shù)據(jù)段的默認(rèn)屬性為,READWRITE,;,CODE16,和,CODE32,偽指令,CODE16,偽指令指示匯編編譯器后面的指令為,16,位的,Thumb,指令;,CODE32,偽指令指示匯編編譯器后面的指令為,32,位的,ARM,指令;,CODE16CODE32,舉例:,AREA Example CODE,READONLY CODE32,END,偽指令,END,偽指令用于指示匯編編譯器源文件已結(jié)束,.,每一個(gè)匯編源文件均要使用一個(gè),END,偽指令,指示本源程序結(jié)束;,END,舉例:,.;,匯編文件內(nèi)容,END,ENTRY,偽指令,ENTRY,偽指令用于指定程序的入口點(diǎn):,ENTRY,舉例:,AREA,EXample,CODE,READONLY,ENTRYCODE32START MOV R1,#0 x10.,EQU,偽指令,EQU,偽指令為數(shù)字常量,基于寄存器的值和程序中的標(biāo)號(hào)定義一個(gè)名稱。
與,EQU,同義:,name EQU,expr,type,舉例:,T_bit,EQU 0 x20 ABCD EQU label+8,EXPORT,和,GLOBAL,偽指令,EXPORT,聲明一個(gè)符號(hào)可以被其它文件引用,.,相當(dāng)于聲明了一個(gè)全局變量,.GLOBAL,與,EXPORT,相同:,EXPORT symbolGLOBAL symbol,舉例:,EXPORT,InitStack,GLOBAL Vectors,IMPORT,和,EXTERN,偽指令,IMJPORT,偽指令指示編譯器當(dāng)前的符號(hào)不是在本源文件中定義的,而是在其他源文 件中定義的,在本源文件中可能引用該符號(hào),.EXTERN,與,IMPORT,相同:,IMPORT symbolEXTERN symbol,舉例:,IMPORT,InitStack,EXTERN Vectors,GET,和,INCLUDE,偽指令,GET,偽指令將一個(gè)源文件包含到當(dāng)前源文件中,并將被包含的文件在具當(dāng)前位置進(jìn) 行匯編處理,INCLUDE,與,GFT,同義:,GET filenameINCLUDE filename,舉例:,INCLUDE s3c44b0.inc,INCBIN,偽指令,INCBIN,偽指令將一個(gè)文件包含到當(dāng)前源文件中,而被包含的文件不進(jìn)行匯編處理:,INCBIN filename,舉例:,INCBIN,charlib.bin,ARM,匯編程序設(shè)計(jì),文件格式,編寫(xiě)規(guī)范,子程序調(diào)用,數(shù)據(jù)塊拷貝,查表操作,完整的例子,文件格式,匯編規(guī)范,標(biāo)號(hào)必須在一行的頂格書(shū)寫(xiě),其后面不要添加,:,,而指令均不能頂格書(shū)寫(xiě),;,ARM,匯編器對(duì)標(biāo)識(shí)符大小寫(xiě)敏感,書(shū)寫(xiě)標(biāo)號(hào)及指令時(shí)字母大小寫(xiě)要一致,;,注釋使用,;,,注釋內(nèi)容由,;,開(kāi)始到此行 結(jié)束,注釋可以在一行的頂格書(shū)寫(xiě),;,匯編規(guī)范,正確的例子,.Str1 SETS My string.0USR_STACK EQU 64START LDR R0,=0 x11223456;,地址送,R0MOV R1,#0LOOPMOV R2,#2,匯編規(guī)范,不正確的例子,.START MOV R0,#1ABC:MOV R1,#2MOV R2,#3loop,Mov,R2,#3B Loop,子程序調(diào)用,用,BL,指令進(jìn)行調(diào)用,該指令會(huì)把返回的,PC,值保存在,LR,舉例,.BL DELAY,;調(diào)用子程序,.DELAY.MOV PC,LR,;子程序返回,數(shù)據(jù)比較跳轉(zhuǎn),匯編程序可以使用,CMP,指令進(jìn)行兩個(gè)數(shù)據(jù)比較,然后調(diào)用相應(yīng)的,ARM,條件碼,實(shí)現(xiàn)跳轉(zhuǎn);,舉例,CMP R5,#10BEQ DOEQUAL.CMP R1,R2ADDHI R1,R1,#10ADDLS R1,R1,#5.ANDS R1,R1,#0 x80BNE WAIT,循環(huán),MOV R1,#10;,循環(huán)次數(shù),LOOP.;,循環(huán)體,SUBS R1,R1,#1BNE LOOP.,數(shù)據(jù)塊復(fù)制,LDR R0,=DATA_DSTLDR R1,=DATA_SRCMOV R10,#10LOOP LDMIA R1!,R2-R9STMIA R0!,R2-R9SUBS R10,R10,#1BNE LOOP,棧操作,ARM,使用存儲(chǔ)器訪問(wèn)指令,LDM/STM,實(shí)現(xiàn)棧操作,用于子程序寄存器保存,.,注意,使用 堆棧時(shí),要先分配好堆??臻g,設(shè)置好寄存器,R13(,即堆棧指針,SP),否則操作失敗,.,舉例,STMFD SP!,R0-R7,LR.BL DELAY.LDMFD SP!,R0-。
