1、嵌入式系统及应用嵌入式系统及应用 第六章第六章 ARM汇编语言程序设计汇编语言程序设计ARM伪指令伪指令汇编程序设计汇编程序设计ARM伪指令伪指令伪指令不像机器指令那样在处理器运行期伪指令不像机器指令那样在处理器运行期间由机器执行,而是在汇编时会被合适的间由机器执行,而是在汇编时会被合适的机器指令代替机器指令代替,实现真正机器指令操作;实现真正机器指令操作;地址读取伪指令地址读取伪指令lADRADR伪指令伪指令小范围的地址读取伪指令.ADR 指令将基于 PC 相对偏移的地址值读取到寄存器中.在汇编编译源程序时,ADR伪指令被编译器替换成一条合适的指令.通常,编译器用一条ADD指令或SUB指令来
2、实现该ADR伪指令的功能;l指令格式:指令格式:ADRcond register,experADRcond register,exper地址读取伪指令地址读取伪指令lADRLADRL伪指令伪指令中等范围的地址读取伪指令.ADRL 指令将基于 PC 相对偏移的地址值或基于寄存器 相对偏移的地址值读取到寄存器中,比 ADR 伪指令可以读取更大范围的地址。在汇编编译源程序时,ADRL 伪指令被编译器替换成两个条合适的指令。l指令格式指令格式ADRLcond register,exper ADRLcond register,exper 地址读取伪指令地址读取伪指令lLDRLDR伪指令伪指令大范围的地址
3、读取伪指令.LDR 伪指令用于加载 32 位的立即数或一个地址值到指定 寄存器.l指令格式指令格式LDRcondregister,=expr/label_expr LDRcondregister,=expr/label_expr l举例举例 LDR R0,=0 x123456LDR R0,=0 x123456LDR R0,=DATA_BUFFER+0 x10LDR R0,=DATA_BUFFER+0 x10.LTORGLTORGNOP伪指令伪指令l空操作伪指令空操作伪指令,无操作,用于实现延时;无操作,用于实现延时;l举例举例DELAY1DELAY1NOPNOPNOPNOPNOPNOPSUBS
4、 R1,R1,#1SUBS R1,R1,#1BNE DELAY1 BNE DELAY1 变量定义伪指令变量定义伪指令l全局变量声明全局变量声明GBLA variable:全局数值变量GBLL variable:全局逻辑变量GBLS variable:全局字符串变量l局部变量声明局部变量声明LBLA variable:局部数值变量LBLL variable:局部逻辑变量LBLS variable:局部字符串变量变量赋值伪指令变量赋值伪指令l给变量复制:给变量复制:SETA 伪指令用于给一个全局/局部的算术变量赋值.SETL 伪指令用于给一个全局/局部的逻辑变量赋值.SETS 伪指令用于给一个全局
5、/局部的字符串变量赋值.变量定义变量定义/赋值伪指令举例赋值伪指令举例GBLL CodeDbgGBLL CodeDbgCodeDbg SETL TRUECodeDbg SETL TRUE.GBLA ByteNoGBLA ByteNoByteNo SETA 8ByteNo SETA 8.GBLS ErrStrGBLS ErrStrErrStr SETS No semaphone.ErrStr SETS No semaphone.RLIST伪指令伪指令 RLIST RLIST 为一个通用寄存器列表定义名称:为一个通用寄存器列表定义名称:name RLIST reglistname RLIST re
6、glist 举例:举例:LoReg RLIST R0-R7LoReg RLIST R0-R7数据定义伪指令数据定义伪指令 数据定义伪指令用于数据表定义数据定义伪指令用于数据表定义,文字池定文字池定义义,数据空间分配等:数据空间分配等:声明一个文字池:声明一个文字池:LTORG LTORG 分配一块内存空间分配一块内存空间,并用并用0 0初始化初始化:SPACE:SPACE分配一段字节的内存单元分配一段字节的内存单元,并用指定的数据并用指定的数据初始化:初始化:DCB DCB 分配一段字的内存单元分配一段字的内存单元,并用指令的数据初并用指令的数据初始化:始化:DCD DCD 和和 DCDU D
7、CDU LTORG伪指令伪指令 LTORG LTORG 用于声明一个文字池用于声明一个文字池(literal-(literal-pool),pool),在使用在使用 LDR LDR 伪指令时伪指令时,要在适当的要在适当的地址加入地址加入 LTORG LTORG 声明声明 文字池文字池,这样就会把这样就会把要加载的数据保存在文字池内要加载的数据保存在文字池内,再用再用 ARM ARM 的加载指令读出数据:的加载指令读出数据:LTORGLTORG 举例:举例:LDR R0,=0 x12345678LDR R0,=0 x12345678ADD R1,R1,R0ADD R1,R1,R0MOV PC,L
8、RMOV PC,LRLTORGLTORGSPACE伪指令伪指令 SPACE SPACE 用于分配一块内存单元用于分配一块内存单元,并用并用 0 0 初初始化始化.%.%与与 SPACE SPACE 同义:同义:label SPACE exprlabel SPACE expr 举例:举例:DataBuf SPACE 1000DataBuf SPACE 1000;分配分配10001000字节字节DCB伪指令伪指令 DCB DCB 用于分配一段字节内存单元用于分配一段字节内存单元,并用伪指并用伪指令中的令中的 expr expr 初始化初始化.一般可用来定义数一般可用来定义数 据表格据表格,或文字符
9、串或文字符串.=.=与与 DCB DCB 同义:同义:label DCB expr,expr,expr.label DCB expr,expr,expr.举例:举例:DISPTAB DISPTAB DCB 0 x33,0 x43,0 x53DCB 0 x33,0 x43,0 x53DCB 0 x10,0 x20,0 x30DCB 0 x10,0 x20,0 x30ERRSTR ERRSTR DCB Send data error.,0DCB Send data error.,0DCD伪指令伪指令 DCDDCD用于分配一段字内存单元用于分配一段字内存单元,并用伪指令并用伪指令中的中的exprex
10、pr初始化初始化.&.&与与 DCD DCD 同义:同义:label DCD expr,expr,exprlabel DCD expr,expr,expr 举例:举例:VectorsVectorsLDR PC,ResetAddrLDR PC,ResetAddrLDR PC,UndefinedAddrLDR PC,UndefinedAddrResetAddrResetAddrDCDDCD ResetResetUndefinedAddr DCD UndefinedUndefinedAddr DCD UndefinedResetReset.汇编控制伪指令汇编控制伪指令 汇编控制伪指令用于条件汇编汇编
11、控制伪指令用于条件汇编,宏定义宏定义,重重复汇编控制等:复汇编控制等:条件汇编控制条件汇编控制:IF,ELSE:IF,ELSE 和和 ENDIF ENDIF 宏定义宏定义:MACRO:MACRO 和和 MEND MEND 重复汇编重复汇编:WHILE:WHILE 及及 WEND WEND IF、ELSE和和ENDIF伪指令伪指令 IF,ELSEIF,ELSE和和ENDIF ENDIF 伪指令能够根据条件把一伪指令能够根据条件把一段代码包括在汇编程序内或将其排除段代码包括在汇编程序内或将其排除 在程在程序之外:序之外:IF logical_expr IF logical_expr.ELSEELS
12、E.ENDIF ENDIF MACRO和和MEND伪指令伪指令 MACRO MACRO 和和 MEND MEND 伪指令用于宏定义伪指令用于宏定义.MACRO.MACRO 标识宏定义的开始标识宏定义的开始,MEND,MEND 标识宏定义久的标识宏定义久的 结束结束.用用MACROMACRO及及MENDMEND定义的一段代码定义的一段代码,称为称为宏定义体:宏定义体:MACROMACRO$label$label macroname para1para2macroname para1para2;宏体定义宏体定义MENDMENDMACRO和和MEND伪指令伪指令 举例:举例:MCAROMCARO$I
13、RQ_Label$IRQ_LabelHANDLERHANDLER$IRQ_Exception$IRQ_ExceptionEXPORT$IRQ_LableEXPORT$IRQ_LableIMPORT$IRQ_ExceptionIMPORT$IRQ_Exception$IRQ_Lable$IRQ_LableSUB LR,LR,#4SUB LR,LR,#4STMFD SP!,R0-R3,R12,LRSTMFD SP!,R0-R3,R12,LRMRS R3,STSRMRS R3,STSRSTMFD SP!,R3STMFD SP!,R3.MENDMENDDCD伪指令伪指令lWHILE WHILE 和和
14、WEND WEND 伪指令用于根据条件重复伪指令用于根据条件重复汇编相同的或几乎相同的一段源程序:汇编相同的或几乎相同的一段源程序:WHILE logical_exprWHILE logical_expr WENDWENDl举例:举例:WHILE no 5WHILE no 5no SETA no+1no SETA no+1.WENDWEND杂项伪指令杂项伪指令l边界对齐边界对齐:ALIGN:ALIGNl段定义段定义:AREA:AREAl指令集定义指令集定义:CODE16:CODE16 和和 CODE32 CODE32 l汇编结束汇编结束:END:END l程序入口程序入口:ENTRY:ENTR
15、Y l常量定义常量定义:EQU:EQU l声明符号可以被外部引用声明符号可以被外部引用:EXPORT:EXPORT和和GLORBAL GLORBAL l声明一个外部符号声明一个外部符号:IMPORT:IMPORT 和和 EXTERN EXTERN l包含文件包含文件:GET:GET 和和 INCLUDE INCLUDE l包含不被汇编的文件包含不被汇编的文件:INCBIN :INCBIN ALIGN伪指令伪指令lALIGN ALIGN 伪指令通过添加补丁字节使当前位伪指令通过添加补丁字节使当前位置满足一定的对齐方式:置满足一定的对齐方式:ALIGN exprALIGN exprl举例:举例:.
16、ByteBufByteBufDCBDCB0 x100 x10ALIGN 4ALIGN 4.AREA伪指令伪指令lAREA AREA 伪指令用于定义一个代码段或数据伪指令用于定义一个代码段或数据段段.ARM .ARM 汇编程序设计采用分段式设计汇编程序设计采用分段式设计,一一 个个 ARM ARM 源程序至少需要一个代码段源程序至少需要一个代码段,大的大的程序可以包含多少个代码段及数据段:程序可以包含多少个代码段及数据段:AREA sectionnameAREA sectionname,attr,attr,attr,attr l举例:举例:AREA Example,CODE,READNOLY A
17、REA Example,CODE,READNOLY AREA伪指令伪指令lALIGN:ALIGN:定义对齐方式定义对齐方式lCODECODE:定义代码段:定义代码段lCOMDEFCOMDEF:定义一个可包含代码和数据的通用段:定义一个可包含代码和数据的通用段lCOMMONCOMMON:定义一个通用的段:定义一个通用的段lDATADATA:定义数据段:定义数据段lNOINITNOINIT:无需初始化:无需初始化lREADONLYREADONLY:指定本段为只读:指定本段为只读,代码段的默认属性代码段的默认属性为为 READONLYREADONLY;lREADWRITEREADWRITE:指定本段
18、为可读可写:指定本段为可读可写.数据段的默认数据段的默认属性为属性为 READWRITEREADWRITE;CODE16和和CODE32伪指令伪指令lCODE16 CODE16 伪指令指示汇编编译器后面的指令伪指令指示汇编编译器后面的指令为为 16 16 位的位的 Thumb Thumb 指令;指令;CODE32 CODE32 伪指令伪指令指示汇编编译器后面的指令为指示汇编编译器后面的指令为 32 32 位的位的 ARM ARM 指令;指令;CODE16CODE16CODE32 CODE32 l举例:举例:AREA Example CODE,READONLY AREA Example CODE
19、,READONLY CODE32 CODE32 END伪指令伪指令lEND END 伪指令用于指示汇编编译器源文件已伪指令用于指示汇编编译器源文件已结束结束.每一个汇编源文件均要使用一个每一个汇编源文件均要使用一个 END END 伪指令伪指令,指示本源程序结束;指示本源程序结束;END END l举例:举例:.;汇编文件内容汇编文件内容END END ENTRY伪指令伪指令lENTRY ENTRY 伪指令用于指定程序的入口点:伪指令用于指定程序的入口点:ENTRY ENTRY l举例:举例:AREA EXample,CODE,READONLYAREA EXample,CODE,READONL
20、YENTRYENTRYCODE32CODE32START MOV R1,#0 x10START MOV R1,#0 x10.EQU伪指令伪指令lEQU EQU 伪指令为数字常量,基于寄存器的值伪指令为数字常量,基于寄存器的值和程序中的标号定义一个名称。和程序中的标号定义一个名称。*与与 EQU EQU 同义:同义:name EQU expr,type name EQU expr,type l举例:举例:T_bit EQU 0 x20 T_bit EQU 0 x20 ABCD EQU label+8 ABCD EQU label+8 EXPORT和和GLOBAL伪指令伪指令lEXPORT EXP
21、ORT 声明一个符号可以被其它文件引用声明一个符号可以被其它文件引用.相当于声明了一个全局变量相当于声明了一个全局变量.GLOBAL.GLOBAL 与与 EXPORT EXPORT 相同:相同:EXPORT symbolEXPORT symbolGLOBAL symbol GLOBAL symbol l举例:举例:EXPORT InitStackEXPORT InitStackGLOBAL VectorsGLOBAL VectorsIMPORT和和EXTERN伪指令伪指令lIMJPORT IMJPORT 伪指令指示编译器当前的符号不伪指令指示编译器当前的符号不是在本源文件中定义的是在本源文件中
22、定义的,而是在其他源文而是在其他源文 件中定义的件中定义的,在本源文件中可能引用该符号在本源文件中可能引用该符号.EXTERN EXTERN 与与 IMPORT IMPORT 相同相同 :IMPORT symbolIMPORT symbolEXTERN symbol EXTERN symbol l举例:举例:IMPORT InitStackIMPORT InitStackEXTERN VectorsEXTERN VectorsGET和和INCLUDE伪指令伪指令lGET GET 伪指令将一个源文件包含到当前源文伪指令将一个源文件包含到当前源文件中件中,并将被包含的文件在具当前位置进并将被包含的
23、文件在具当前位置进 行汇编处理行汇编处理 INCLUDE INCLUDE 与与 GFT GFT 同义:同义:GET filenameGET filenameINCLUDE filename INCLUDE filename l举例:举例:INCLUDE s3c44b0.inc INCLUDE s3c44b0.inc INCBIN伪指令伪指令lINCBIN INCBIN 伪指令将一个文件包含到当前源文伪指令将一个文件包含到当前源文件中件中,而被包含的文件不进行汇编处理:而被包含的文件不进行汇编处理:INCBIN filename INCBIN filename l举例:举例:INCBIN cha
24、rlib.bin INCBIN charlib.bin ARM汇编程序设计汇编程序设计l文件格式文件格式l编写规范编写规范l子程序调用子程序调用l数据块拷贝数据块拷贝l查表操作查表操作l完整的例子完整的例子文件格式文件格式汇编规范汇编规范l标号必须在一行的顶格书写标号必须在一行的顶格书写,其后面不要添其后面不要添加加:,而指令均不能顶格书写,而指令均不能顶格书写;lARM ARM 汇编器对标识符大小写敏感,书写标汇编器对标识符大小写敏感,书写标号及指令时字母大小写要一致号及指令时字母大小写要一致;l注释使用注释使用;,注释内容由,注释内容由;开始到此开始到此行行 结束,注释可以在一行的顶格书写
25、结束,注释可以在一行的顶格书写;汇编规范汇编规范l正确的例子正确的例子.Str1 Str1 SETS SETS My string.0My string.0USR_STACK USR_STACK EQU EQU 6464START START LDR R0,=0 x11223456LDR R0,=0 x11223456;地址送地址送R0R0MOV R1,#0MOV R1,#0LOOPLOOPMOV R2,#2MOV R2,#2汇编规范汇编规范l不正确的例子不正确的例子.START MOV R0,#1START MOV R0,#1ABC:ABC:MOV R1,#2MOV R1,#2MOV R2,
26、#3MOV R2,#3looploopMov R2,#3Mov R2,#3B LoopB Loop子程序调用子程序调用l用用 BL BL 指令进行调用指令进行调用,该指令会把返回的该指令会把返回的 PC PC 值保存在值保存在 LRLRl举例举例.BL DELAYBL DELAY;调用子程序;调用子程序.DELAYDELAY.MOV PC,LRMOV PC,LR;子程序返回;子程序返回数据比较跳转数据比较跳转l汇编程序可以使用汇编程序可以使用CMPCMP指令进行两个数据比较指令进行两个数据比较,然后调用相应的然后调用相应的ARMARM条件码条件码,实现跳转;实现跳转;l举例举例CMP R5,#
27、10CMP R5,#10BEQ DOEQUALBEQ DOEQUAL.CMP R1,R2CMP R1,R2ADDHI R1,R1,#10ADDHI R1,R1,#10ADDLS R1,R1,#5ADDLS R1,R1,#5.ANDS R1,R1,#0 x80ANDS R1,R1,#0 x80BNE WAITBNE WAIT循环循环MOV R1,#10MOV R1,#10;循环次数循环次数LOOP.LOOP.;循环体循环体SUBS R1,R1,#1SUBS R1,R1,#1BNE LOOPBNE LOOP.数据块复制数据块复制LDR R0,=DATA_DSTLDR R0,=DATA_DSTLDR
28、 R1,=DATA_SRCLDR R1,=DATA_SRCMOV R10,#10MOV R10,#10LOOP LDMIA R1!,R2-R9LOOP LDMIA R1!,R2-R9STMIA R0!,R2-R9STMIA R0!,R2-R9SUBS R10,R10,#1SUBS R10,R10,#1BNE LOOPBNE LOOP栈操作栈操作lARM ARM 使用存储器访问指令使用存储器访问指令 LDM/STM LDM/STM 实现栈实现栈操作操作,用于子程序寄存器保存用于子程序寄存器保存.注意注意,使用使用 堆堆栈时栈时,要先分配好堆栈空间要先分配好堆栈空间,设置好寄存器设置好寄存器 R1
29、3(R13(即堆栈指针即堆栈指针 SP),SP),否则操作失败否则操作失败.l举例举例 STMFD SP!,R0-R7,LRSTMFD SP!,R0-R7,LR.BL DELAYBL DELAY.LDMFD SP!,R0-R7,PCLDMFD SP!,R0-R7,PC散转散转CMP R0,#MAXINDEXCMP R0,#MAXINDEXADDLO PC,PC,R0,LSL#2ADDLO PC,PC,R0,LSL#2B ERRORB ERRORB FUN1B FUN1;散转表散转表B FUN2B FUN2B FUN3B FUN3.查表操作查表操作.LDR R3,=DIS_TABLDR R3,=
30、DIS_TABLDR R2,R3,R5,LSL#2LDR R2,R3,R5,LSL#2.;下表是;下表是0 0F F的字模的字模DISR_TAB DISR_TAB DCD 0 xC0,0 xF9,0 xA4,0 x99,0 x92DCD 0 xC0,0 xF9,0 xA4,0 x99,0 x92DCD 0 x82,0 xF8,0 x80,0 x90,0 x88DCD 0 x82,0 xF8,0 x80,0 x90,0 x88长跳转长跳转.ADD LR,PC,#4ADD LR,PC,#4LDR PC,PC,#-4LDR PC,PC,#-4DCD LADR_FUNDCD LADR_FUN.或使用或
31、使用LDR PC,=LADR_FUNLDR PC,=LADR_FUN一个完整的例子一个完整的例子ABC EQU 0 x12ABC EQU 0 x12AREA Example,CODEAREA Example,CODE,READONLYREADONLYENTRYENTRYCODE32CODE32ADR R0,Thumb_START+1ADR R0,Thumb_START+1BX R0BX R0CODE16CODE16Thumb_STARTThumb_STARTMOV R1,#ABCMOV R1,#ABCADD R1,R1,#0 x10ADD R1,R1,#0 x10B Thumb_STARTB Thumb_STARTENDEND