《基于ARM的嵌入式程序设计.ppt》由会员分享,可在线阅读,更多相关《基于ARM的嵌入式程序设计.ppt(230页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第五章基于ARM的嵌入式程序设计5.1 ARM汇编语言的伪操作、宏指令与伪指令汇编语言的伪操作、宏指令与伪指令5.2 ARM汇编语言程序设计汇编语言程序设计5.3 嵌入式嵌入式C语言程序设计基础语言程序设计基础5.4 嵌入式嵌入式C语言程序设计实例语言程序设计实例5.5 嵌入式嵌入式C语言程序设计技巧语言程序设计技巧5.6 C与汇编语言混合编程与汇编语言混合编程5.7 基于基于Embest IDE for ARM 环境的软件开发环境的软件开发实例实例5.1 ARM汇编语言的伪操作、宏指令与伪指令汇编语言的伪操作、宏指令与伪指令5.1.1两种常见的ARM编译开发环境5.1.2ADS编译环境下的伪
2、操作和宏指令5.1.3GNU编译环境下的伪操作和宏指令5.1.4ARM汇编语言的伪指令 两种常见的ARM编译开发环境ADS/SDT IDE开发环境:它由ARM公司开发,使用了CodeWarrior公司的编译器;集成了GNU开发工具的IDE开发环境:它由GNU的汇编器as、交叉编译器gcc、和链接器ld等组成。编译环境下的伪操作和宏指令ADS编译环境下的伪操作可分为以下几类:符号定义(SymbolDefinition)伪操作数据定义(DataDefinition)伪操作汇编控制(AssemblyControl)伪操作信息报告(Reporting)伪操作其他(Miscellaneous)伪操作 符
3、号定义伪操作伪操作语法格式作用GBLAGBLAVariable声明一个全局的算术变量,并将其初始化成0。GBLLGBLLVariable声明一个全局的逻辑变量,并将其初始化成FALSE。GBLSGBLSVariable声明一个全局的字符串变量,并将其初始化成空串“”。LCLALCLAVariable声明一个局部的算术变量,并将其初始化成0。LCLLLCLLVariable声明一个局部的逻辑变量,并将其初始化成FALSE。LCLSLCLSVariable声明一个局部的串变量,并将其初始化成空串“”。SETASETAVariableexpr给一个全局或局部算术变量赋值。SETLSETLVariab
4、leexpr给一个全局或局部逻辑变量赋值。SETSSETSVariableexpr给一个全局或局部字符串变量赋值。RLISTname LIST list of registers为一个通用寄存器列表定义名称。CNnameCNexpr为一个协处理器的寄存器定义名称。CPnameCPexpr为一个协处理器定义名称。DN/SNnameDN/SNexprDN/SN为一个双精度/单精度的VFP寄存器定义名称。FNnameFNexpr为一个FPA浮点寄存器定义名称。数据定义伪操作伪操作语法格式作用LTORGLTORG声明一个数据缓冲池(也称为文字池)的开始。MAPMAPexpr,base-register
5、定义一个结构化的内存表(StorageMap)的首地址。FIELDlabelFIELDexpr定义一个结构化内存表中的数据域。SPACElabelSPACEexpr分配一块连续内存单元,并用0初始化。DCBlabel DCB expr,expr分配一段字节内存单元,并用expr初始化。DCD/DCDUlabel DCD expr,expr分配一段字内存单元。DCDOlabelDCDOexpr,expr分配一段字对齐的字内存单元。DCFD/DCFDUlabelDCFDUfpliteral,fpliteral为双精度的浮点数分配字对齐的内存单元。DCFS/DCFSUlabel DCFS U fpl
6、iteral,fpliteral为单精度的浮点数分配字对齐的内存单元。DCIlabel DCI expr,expr在ARM代码中分配一段字对齐的内存单元;在Thumb代码中,分配一段半字对齐的半字内存单元。DCQ/DCQUlabelDCQUliteral,literal分配一段以双字(8个字节)为单位的内存DCW/DCWUlabel DCWUexpr,exprDCW用于分配一段半字对齐的半字内存单元。汇编控制伪操作 伪操作语法格式作用IF,ELSE及ENDIFIFlogicalexpressionELSEENDIF能够根据条件把一段源代码包括在汇编语言程序内或者将其排除在程序之外。WHILE及
7、WENDWHILElogicalexpressionWEND能够根据条件重复汇编相同的一段源代码。MACRO、MEND及MEXITMACRO$labelmacroname$parameter,$parameter;宏代码MENDMACRO标识宏定义的开始,MEND标识宏定义的结束。MERIT用于从宏中跳转出去。用MACRO和MEND定义的一段代码,称为宏定义体。通过宏名称来调用宏。信息报告伪操作伪操作语法格式作用ASSERTASSERTlogicalexpression对汇编程序的第二遍扫描中,如果其中ASSERT中条件不成立,ASSERT伪操作将报告该错误信息。INFOINFOnumeric
8、-expression,string-expression在汇编处理过程的第一遍扫描或者第二遍扫描时INFO伪操作报告诊断信息。OPTOPTn通过OPT伪操作可以在源程序中设置列表选项。TTLTTLtitle在列表文件的每一页的开头插入一个标题。SUBTSUBTsubtitle在列表文件的每一页的开头插入一个子标题。其他伪操作伪操作语法格式作用CODE16CODE16告诉汇编编译器后面的指令序列为16位的Thumb指令CODE32CODE32告诉汇编编译器后面的指令序列为32位的ARM指令。EQUnameEQUexpr,type为数字常量、基于寄存器的值和程序中的标号(基于PC的值)定义一个字
9、符名称。AREAAREA sectionname,attr ,attr定义一个代码段或者数据段。ENTRYENTRY指定程序的入口点。ENDEND告诉编译器已经到了源程序结尾。ALIGNALIGNexpr,offset通过添加补丁字节使当前位置满足一定的对齐方式。EXPORT/GLOBALEXPORTsymbolWEAK声明一个符号可以被其他文件引用,相当于声明了一个全局变量。IMPORTIMPORTsymbolWEAK告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。EXTERNEXTERNsymbolWEAK告诉编译器当前的符号不是在本源文件
10、中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号。GET/INCLUDEGETfilename将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。INCBININCBINfilename将一个文件包含到当前源文件中,被包含的文件不进行汇编处理。KEEPKEEPsymbol告诉编译器将局部符号包含在目标文件的符号表中。NOFPNOFP禁止源程序中包含浮点运算指令。REQUIREREQUIRElable指定段之间的相互依赖关系。RNnameRNexpr为一个特定的寄存器定义名称。ROUTnameROUT定义局部变量的有效范围。符号定义伪操作1、GBLA、GBLL
11、和GBLS说明:声明一个ARM程序中的全局变量,并在默认情况下将其初始化GBLA:声明一个全局算术变量,初始化为0GBLL:声明一个全局逻辑变量,初始化为FALSEGBLS:声明一个全局字符串变量,初始化为空串“”语法格式:Variable符号定义伪操作举例:GBLAarithmaticArithmaticSETA0 xEFSPACEarithmaticGBLLlogicalLogicalSETLTRUE符号定义伪操作2、LCLA、LCLL和LCLS说明:声明一个ARM程序中的局部变量,并在默认情况下将其初始化LCLA:声明一个局部算术变量,初始化为0LCLL:声明一个局部逻辑变量,初始化为F
12、ALSELCLS:声明一个局部字符串变量,初始化为空串“”语法格式:Variable符号定义伪操作举例:MACRO$labelmessage$aLCLSstringstringSETS“error”$labelINFO0,”string”:CC:STR:$aMEND符号定义伪操作3、SETA、SETL和SETS说明:给ARM程序中的全局或局部变量赋值。SETA:给一个全局或局部算术变量赋值SETL:给一个全局或局部逻辑变量赋值SETS:给一个全局或局部字符串变量赋值语法格式:Variableexpr符号定义伪操作举例:GBLAarithmaticArithmaticSETA0 xEFSPACE
13、arithmaticGBLLlogicalLogicalSETLTRUE符号定义伪操作4、RLIST说明:为一个通用寄存器列表定义名称语法格式:nameRLISTlistofregisters举例:ListRLISTR0-R3STMDFSP!List符号定义伪操作5、CN说明:为一个协处理器的寄存器定义名称语法格式:nameCNexpr举例:PowerCN6符号定义伪操作6、CP说明:为一个协处理器定义名称语法格式:nameCPexpr举例:DzxCP6符号定义伪操作7、DN和SN说明:DN为一个双精度的VFP寄存器定义名称SN为一个单精度的VFP寄存器定义名称语法格式:nameDNexprn
14、ameSNexpr举例:heightDN6widthSN20符号定义伪操作8、FN说明:FN为一个FPA浮点寄存器定义名称语法格式:nameFNexpr举例:lengthFN6数据定义伪操作1、LTORG说明:用于声明一个数据缓冲池的开始。当程序中使用LDR之类的指令时,数据缓冲池的使用可能越界。为防止越界发生,可使用LTORG伪操作定义数据缓冲池。通常大的代码段可使用多哥数据缓冲池。ARM汇编编译器一般把数据缓冲池放在代码段的最后面。语法格式:LTORG举例:AREAExample,CODE,READONLYstartBLfunel.funelLDRR1,=0 x8000MOVPC,LRLT
15、ORGDataSPACE40END数据定义伪操作2、MAP说明:用于定义一个结构化的内存表的首地址。此时,内存表的位置计数器设置成该地址值。MAP也可以用”代替语法格式:MAPexpr,base-register举例:MAPfunMAP0 x100,R9数据定义伪操作3、FIELD说明:用于定义一个结构化的内存表的数据域。FIELD也可以用”#”代替语法格式:labelFIELDexpr使用说明:MAP和FIELD配合使用来定义结构化的内存表结构。MAP定义内存表的首地址;FIELD定义内存表中各数据域的字节长度,并可为每一个数据域指定一个标号,其他指令可引用该标号。MAP中的base-reg
16、ister寄存器值对于其后所有的FIELD定义的数据域是默认使用的,直到遇到新的包含base-register的MAP操作。需要注意的是,MAP和FIELD仅仅是定义数据结构,它们并不实际分配内存单元。由MAP和FIELD定义的内存表有3种:基于绝对地址的内存表、基于相对地址的内存表和基于PC的内存表数据定义伪操作例1:基于绝对地址的内存表定义一个内存表,其首地址为固定地址8192(0 x2000),该内存表中包含5个数据域;consta长度为4字节;constb长度为4字节;x长度为8字节;y长度为8字节;string长度为16字节。MAP8192constaFIELD4constbFIEL
17、D4xFIELD8yFIELD8stringFIELD16在指令中这样引用内存表中的数据域:LDRR0,consta数据定义伪操作例2:基于相对地址的内存表定义一个内存表,其首地址为0与R9寄存器的和,该内存表中包含5个数据域;consta长度为4字节;constb长度为4字节;x长度为8字节;y长度为8字节;string长度为16字节。MAP0,R9constaFIELD4constbFIELD4xFIELD8yFIELD8stringFIELD16在指令中这样引用内存表中的数据域:ADRR9,FIELDLDRR5,constb数据定义伪操作例3:基于PC的内存表定义一个内存表,其首地址为P
18、C的值,该内存表中包含5个数据域;consta长度为4字节;constb长度为4字节;x长度为8字节;y长度为8字节;string长度为16字节。DataSPACE100MAPDataconstaFIELD4constbFIELD4xFIELD8yFIELD8stringFIELD16在指令中这样引用内存表中的数据域:LDRR5,constb数据定义伪操作说明:当FIELD中的操作数为0时,其中的标号即为当前内存单元的地址。由于其中操作数为0,汇编器处理了该操作后,内存表的位置计数器的值并不改变。可利用这项技术来判断当前内存的使用没有超过程序分配的可用内存。例4:特殊内存表定义一个内存表,其首
19、地址为PC的值,该内存表中包含5个数据域;consta长度为4字节;constb长度为4字节;x长度为8字节;y长度为8字节;string长度为maxlen字节。startEQU0 x1000endEQU0 x2000MAPstartconstaFIELD4constbFIELD4xFIELD8yFIELD8stringFIELDmaxlenendalertFIELD0ASSERTendalert=endend数据定义伪操作4、SPACE说明:用于分配一块连续内存单元,并用0初始化。可用“%”代替。语法格式:labelSPACEexpr举例:DataSPACE100数据定义伪操作5 5、DCB
20、:DCB:说明:DCB用于分配一块字节单元,并用伪指令中指定的表达式进行初始化。其中,表达式可以为使用双引号的字符串或0255的数字,DCB可用“=”代替。语法格式:labelDCB DCB expr举例:stringDCB“student”数据定义伪操作6 6、DCD/DCDUDCD/DCDU 说明:DCD伪指令用于分配一块字存储单元,并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。DCD也可用“&”代替。而DCDU并不严格字对齐。语法格式:labelDCD DCD exprlabelDCDU DCDU expr举例:Data1DCD1,5,10Data2DCDaddr+4数据定
21、义伪操作7 7、DCDODCDO 说明:DCD伪指令用于分配一块字对齐的字存储单元,并将每个字单元的内容初始化为该单元相对于R9内容的偏移量。语法格式:labelDCDO DCDO expr举例:IMPORTsignDCDOsign数据定义伪操作8 8、DCFD/DCFDUDCFD/DCFDU 说明:DCFD伪指令用于为双精度的浮点数分配字存储单元,并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。而DCFDU并不严格字对齐。语法格式:labelDCFD DCFD exprlabelDCFDU DCFDU expr举例:DCFD1E308,-4E-100DCFDU10000,-0.1
22、,3.1E26数据定义伪操作9 9、DCFS/DCFSUDCFS/DCFSU 说明:DCFS伪指令用于为单精度的浮点数分配字存储单元,并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。而DCFSU并不严格字对齐。语法格式:labelDCFS DCFS exprlabelDCFSU DCFSU expr举例:DCFSE3,-4E-9DCFSU1.0,-1.3,3.1E6数据定义伪操作1010、DCIDCI 说明:在ARM代码中,DCI伪指令用于分配字对齐的字存储单元,并用伪指令中指定的表达式初始化。在THUMB代码中,DCI伪指令用于分配半字对齐的半字存储单元,并用伪指令中指定的表达式
23、初始化。语法格式:labelDCI DCI expr举例:MACRONewinstr$Rd,$RmDCI0 xE16F0F10:OR:($Rd:SHL:12):OR:$RmMEND数据定义伪操作1111、DCQ/DCQUDCQ/DCQU 说明:DCQ伪指令用于分配一块双字存储单元,并用伪指令中指定的表达式初始化,它定义的存储空间是字对齐的。而DCQU并不严格字对齐。语法格式:labelDCQ DCQ-literallabelDCQU DCQU-literal举例:Data1DCQ-100,2_101Data2DCQU1000数据定义伪操作1212、DCW/DCWUDCW/DCWU 说明:DCW
24、伪指令用于分配一块半字存储单元,并用伪指令中指定的表达式初始化,它定义的存储空间是半字对齐的。而DCWU并不严格半字对齐。语法格式:labelDCW DCW exprlabelDCWU DCWU expr举例:Data1DCW-235,748Data2DCWU1000汇编控制伪操作1 1、IF IF、ELSEELSE、ENDIFENDIF IF IF逻辑表达式逻辑表达式 代码段代码段1 1 ELSE ELSE 代码段代码段2 2 ENDIF ENDIF 说明:IF、ELSE、ENDIF伪操作能根据逻辑表达式的成立与否决定是否在编译时加入某个指令序列。IF、ELSE、ENDIF可以分别 用“”、
25、“|”、“”代 替。IF、ELSE、ENDIF伪指令可以嵌套使用。汇编控制伪操作举例:IFVariable=16BNESUB1LDRR0.=SUB0BXR0ELSEBNESUB0.ENDIF汇编控制伪操作2 2、WHILEWHILE、WEND:WEND:WHILE WHILE 逻辑表达式逻辑表达式 代码段代码段 WEND WEND 说明:WHILE和WEND伪指令能根据逻辑表达式的成立与否决定是否循环执行这个代码段。WHILE、WEND伪指令可以嵌套使用。汇编控制伪操作举例:countSETA1WHILEcount=4countSETAcount+1WEND汇编控制伪操作3 3、MACRO M
26、ACRO、MENDMEND MACRO MACRO$标号标号 宏名宏名$参数参数1 1,$参数参数2 2,指令序列指令序列 MEND MEND 说明:MACRO 表明一个宏定义的开始,MEND则表示一个宏的结束,MACRO、MEND前呼后应可以将一段代码定义为一个整体,又称宏,然后就可以在程序中通过宏的名称及参数调用该段代码。MACRO和MEND之间的代码称为宏定义体,在宏定义体的第一行声明宏的原型,宏的原型包含宏名、所需的参数。在源程序被编译时,汇编器将宏调用展开,用宏定义中的指令序列替换程序中的宏调用,并将实际参数的值传递给宏定义中的参数。注意:宏操作可以嵌套使用,并可以在编译时用选项加以
27、控制。汇编控制伪操作4 4、MEXIT:MEXIT:MEXIT MEXIT 说明:MEXIT用于从宏中退出。汇编控制伪操作举例:1、编程实现宏定义体包括2个循环操作和1个子程序调用MACRO$labeljump$a1,$a2$labelloop1.BGE$labelloop1$labelloop2BL$a1BGT$labelloop2ADR$a2.MEND在程序中调用该宏:examjumpsub,det汇编控制伪操作举例:2、编程实现宏定义体完成测试-跳转MACRO$labelTestAndBranch$ds,$re,$aa$labelCMP$re,#0BL$aa$dsMEND在程序中调用该宏
28、:testTestAndBranchnzero,R0,NE信息报告伪操作1 1、ASSERT:ASSERT:语法格式:ASSERT logical expressionASSERT logical expression 说明:ASSERT用来表示程序的编译必须满足一定的条件,如果逻辑表达式不满足,则编译器会报错。举例:ASSERTTopTemp信息报告伪操作2 2、INFOINFO语法格式:INFO numeric-expression,numeric-expression,string-expressionstring-expression 说明:汇编诊断信息显示伪操作。显示用户自定义的错误
29、信息。举例:INFO0,“Version1.0”IFlabel1=label2INFO4,”Dataoverrun”ENDIF信息报告伪操作3 3、OPTOPT语法格式:OPT n n 说明:使用编译选项-list将使编译器产生常规的列表文件。举例:在fun前插入OPT4,fun将在新的一页中显示AREAExample,CODE,READONLYstartBLfuncOPT4func信息报告伪操作4 4、TTLTTL及及SUBTSUBT语法格式:TTLtitle SUBT subtitle SUBT subtitle 说明:TTL在列表文件的页顶部显示一个标题;SUBT在列表文件页标题的下面显
30、示一个子标题。举例:TTLtitle SUBT subtitle SUBT subtitle其他伪操作1 1、CODE16CODE16、CODE32:CODE32:语法格式:CODE16/CODE32 CODE16/CODE32 说明:CODE16伪操作指示编译器后面的代码为16位的Thumb指令。CODE32伪操作指示编译器后面的代码为32位的ARM指令。其他伪操作举例:编程实现程序先在ARM状态下执行,通过BX指令切换到Thumb状态。AERAChangeState,CODE,READONLYCODE32LDRR0,=START+1BXR0CODE16StartMOVR1,#10其他伪操作
31、2 2、EQUEQU语法格式:名称名称 EQU EQU 表达式表达式,类类型型 说明:EQU用于将程序中的数字常量、标号、基于寄存器的值赋予一个等效的名称,这一点类似于C语言中的define,可用“*”代替EQU。如果表达式为32位的常量,我们可以指定表达式的数据类型,类型域可以有以下三种:CODE16/CODE32/DATA其他伪操作举例:XEQU10YEQUlabel+100ZEQU0 x10,CODE32regEQU0 xE01FC080其他伪操作3 3、AREAAREA语法格式:AREA AREA 段名段名 属性,属性,说明:AREA用于定义一个代码段、数据段或者特定属性的段。如果段名
32、以数字开头,那么该段名需用“|”字符括起来,如|7wolf|,用C的编译器产生的代码一般也用“|”括起来。属性部分表示该代码段/数据段的相关属性,多个属性可以用“,”分隔。常见属性如下:DATA:定义数据段。CODE:定义代码段。READONLY:表示本段为只读。READWRITE:表示本段可读写。ALIGN=表达式:对齐方式为2表达式次方,例如:表达式=3,则对齐方式为8字节对齐。表达式的取值范围为031。COMMON属性:定义一个通用段,这个段不包含用户代码和数据。COMDEF属性:定义一个通用段,这个段可包含用户代码和数据。ASSOC=section.指定与本段相连的ELF段。NOINI
33、T指定本数据段仅保留内存单元,而没有将各初始值写入内存单元,或者将各内存单元值初始化伪。其他伪操作4 4、ENTRY:ENTRY:语法格式:ENTRYENTRY 说明:ENTRY用于指定汇编程序的入口。在一个完整的汇编程序中至少要有一个ENTRY,程序中也可以有多个,此时,程序的真正入口点可在链接时指定,但在一个源文件里最多只能有一个ENTRY或者没有ENTRY。其他伪操作5 5、ENDEND语法格式:ENDEND 说明:“END”告诉编译器已经到了 源程序的结尾。其他伪操作6 6、ALIGN:ALIGN:语法格式:ALIGN ALIGN 表达式表达式,偏移量,偏移量 说明:ALIGN伪操作可
34、以通过填充字节使当前的位置满足一定的对齐方式。其中,表达式的值为2的幂,如1、2、4、8、16等,用于指定对齐方式。如果伪操作中没有指定表达式,则编译器会将当前位置对齐到下一个字的位置。偏移量也是个数字表达式,如果存在偏移量,则当前位置的自动对齐到:2的表达式值次方偏移量。如:“ALIGN8”表示将当前位置以2个字的方式对齐。又如“ALIGN4,3”,则当原始位置在0 x0001时,当前位置转到0 x0007(0 x0004+3)。其他伪操作注意:(1)Thumb的伪指令ADR要求地址是字对齐的,而Thumb代码中地址标号可能不是字对齐的。这时就要使用“ALIGN4”使Thumb代码中地址标号
35、是字对齐的。(2)LDRD及STRD指令要求内存单元是8字节对齐的。这样在LDRD及STRD分配内存单元前,要使用ALIGN8实现8字节对齐方式。(3)地址标号通常自身没有对齐要求,而在ARM代码中要求地址标号是字对齐的,在Thumb中要求半字对齐。这样就要采用ALIGN指令调整对齐方式。其他伪操作举例:1、AREAcache,CODE,ALIGN=3;指定该代码;段的指令是8字节对齐的。MOVPC,LRALIGN8;指定下面的指令是8字节对齐的其他伪操作2、将2字节数据放在同一个字的第1字节和第4字节中。AREAExample,CODE,READONLYDCB0 x11ALIGN4,3DCB
36、0 x243、通过ALIGN指令使程序中地址标号字对齐。AREAExample,CODE,READONLYstartLDRR6,=labelMOVPC,LRlabelDCB0 x48ALIGN其他伪操作7 7、EXPORT/GLOBAL EXPORT/GLOBAL EXPORT/GLOBAL EXPORT/GLOBAL 标号标号,WEAK,WEAK 说说明明:EXPORT在程序中声明一个全局标号,该标号可以被其他的文件中的代码引用。用户也可以用GLOBAL代替EXPORT。,WEAK可选项声明其他文件有同名的标号,则该同名标号优先于该标号被引用。8 8、IMPORT:IMPORT:IMPORT
37、 IMPORT 标号标号 ,WEAKWEAK 说说明明:IMPORT告诉编译器这个标号要在当前源文件中使用,但标号是在其他的源文件中定义的。不管当前源文件是否使用过该标号,这个标号都会加入到当前源文件的符号表中。,WEAK选项表示如果所有的源文件都没有找到这个标号的定义,编译器也不会提示错误信息。编译器在多数情况下将该标号置为0,如果这个标号被B或BL指令引用,则将B或BL指令替换为NOP操作。其他伪操作9 9、EXTERN:EXTERN:EXTERN EXTERN 标号标号,WEAK,WEAK 说说明明:EXTERN告诉编译器所使用的标号要在当前源文件中引用,但该标号是在其他的源文件中定义的
38、。与IMPORT不同的是,如果当前源文件实际上没有引用该标号,该标号就不会被加入到当前文件的符号表中。,WEAK选项意义同IMPORT。其他伪操作1 10 0、GET/INCLUDEGET/INCLUDE:GET GET文件名文件名 说明:GET将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置展开进行汇编处理。INCLUDE和GET作用等效的。我们通常这样使用这个伪指令:在某源文件中定义一些宏指令,用MAP和FIELD定义结构化的数据类型,用EQU定义常量的符号名称,然后用GET/INCLUDE将这个源 文 件 包 含 到 其 他 的 源 文 件 中。GET/INCLUDE只能用
39、于包含源文件,包含其他文件则需要使用INCBIN伪指令。其他伪操作注意:通常可在一个源文件中定义宏,用EQU定义常量的符号名称,用MAP和FIELD定义结构化的数据类型,这样的源文件类似于C语言中的.h文件。然后用GET伪操作将这个源文件包含到它们的源文件中,类似于“include*.h”举例:AREAExample,CODE,READONLYGETfile1.sGETC:PROJECTfile2.s其他伪操作1111、INCBIN:INCBIN:INCBIN INCBIN 文件名文件名 说明:INCBIN将一个数据文件或者目标文件包含到当前的源文件中,编译时被包含的文件不作任何变动的存放在当
40、前文件中,编译器从后面开始继续处理。其他伪操作1212、KEEPKEEP KEEP symbol KEEP symbol 说明:告诉编译器将局部符号包含在目标文件的符号表中。默认情况下,编译器仅将下面的符号包含到目标文件的符号表中:被输出的符号;将会被重定位的符号。使用该指令可将局部符号包含在目标文件的符号表中。举例:Label CMP R0,R1 KEEP label其他伪操作1313、NOFPNOFP NOFP NOFP 说明:禁止源程序中包含浮点运算指令。其他伪操作1414、REQUIREREQUIRE REQUIRE label REQUIRE label 说明:用于指定段之间的相互依
41、赖关系。其他伪操作1515、REQUIRE8REQUIRE8和和PRESEERVE8PRESEERVE8 REQUIRE8 REQUIRE8 PRESEERVE8 PRESEERVE8 说明:REQUIRE8指示当前代码中要求数据栈8字节对齐。PRESEERVE8指示当前代码中数据栈是8字节对齐。LDRD和STRD指令要求内存单元地址是8字节对齐的。当在程序中使用这些指令在数据栈中传送数据时,要求数据栈是8字节对齐的,这时需要用REQUIRE8。其他伪操作1616、RNRN name RN expr name RN expr 说明:用于给一个寄存器定义名称,以方便记忆该寄存器的功能。举例:CO
42、UNT RN 6 CHOOSE RN 9其他伪操作1717、ROUT:ROUT:名称名称 ROUT ROUT 说明:ROUT可以给一个局部变量定义作用范围。在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA,而使用ROUT后,局部变量的作用范围为当前ROUT和下一个ROUT之间。5.1.3GNU编译环境下的伪操作和宏指令GNU编译环境下的伪操作可分为以下几类:常量编译控制伪操作汇编程序代码控制伪操作宏及条件编译控制伪操作其他伪操作常量编译控制伪操作伪操作语法格式作用.byte.byteexpr,expr分配一段字节内存单元,并用expr初始化。.hword/.short.hworde
43、xpr,expr分配一段半字内存单元,并用expr初始化。.ascii.asciiexpr,expr定义字符串expr(非零结束符)。.asciz/.string.ascizexpr,expr定义字符串expr(以/0为结束符)。.float/.single.floatexpr,expr定义一个32bitIEEE浮点数expr。.double.doubleexpr,expr定义64bitIEEE浮点数expr。word/.long/.int.wordexpr,expr分配一段字内存单元,并用expr初始化。.fill.fillrepeat,size,value分配一段字节内存单元,用size长
44、度value填充repeat次。.zero.zerosize分配一段字节内存单元,并用0填充内存。.space/.skip.spacesize,value分配一段内存单元,用value将内存单元初始化。汇编程序代码控制伪操作 伪操作语法格式作用.section.sectionexpr定义域中包含的段。.text.textsubsection将操作符开始的代码编译到代码段或代码段子段。.data.datasubsection将操作符开始的数据编译到数据段或数据段子段。.bss.bsssubsection将变量存放到.bss段或.bss段的子段。.code16/.thumb.code16.thum
45、b表明当前汇编指令的指令集选择Thumb指令集。.code32/.arm.code32.arm表明当前汇编指令的指令集选择ARM指令集。.end.end标记汇编文件的结束行,即标号后的代码不作处理。.include.include“filename”将一个源文件包含到当前源文件中。.align/.balign.alignalignment,fill,max通过添加填充字节使当前位置满足一定的对齐方式。宏及条件编译控制伪操作伪操作语法格式作用.macro、.exitm及.endm.macroacronameparameter,parameter.endm.macro伪操作标识宏定义的开始,.en
46、dm标识宏定义的结束。用.macro及.endm定义一段代码,称为宏定义体。.exitm伪操作用于提前退出宏。.ifdef,.else及.endif.ifdefcondition.else.endif当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。其中else可以缺省。其他伪操作 伪操作语法格式作用.eject.eject在汇编符号列表文件中插入一分页符。.list.list产生汇编列表(从.list到.nolist)。.nolist.nolist表示汇编列表结束处。.title.title“heading”使用“heading”作为标题。.sbttl.sbttl“head
47、ing”使用“heading”作为子标题。.ltorg.ltorg在当前段的当前地址(字对齐)产生一个文字池。.req.reqname,expr为一个特定的寄存器定义名称。.err.err使编译时产生错误报告。.print.printstring打印信息到标准输出。.fail.failexpr编译汇编文件时产生警告。常量编译控制伪操作1、.byte语法格式:.byte expr.byte expr 说明:用于分配一段字节对齐的字节内存单元,并用expr初始化。举例:.byte 21,48,89,0 x13常量编译控制伪操作2、.hwod及.short语法格式:.hwod/.short expr
48、 expr 说明:用于分配一段半字对齐的半字内存单元,并用expr初始化。举例:.hwod/.short 21,25,89,0 x43常量编译控制伪操作3、.ascii语法格式:.ascii expr expr 说明:用于定义字符串,并用expr(非0结束符)初始化。举例:.ascii “How are you”常量编译控制伪操作4、.asciz及.string语法格式:.asciz.string expr expr 说明:用于定义字符串,并用expr(以”/0”为结束符)初始化。举例:.asciz “How are you”常量编译控制伪操作5、.float及.single语法格式:.flo
49、at.single expr expr 说明:用于定义一个32位IEEE浮点数。举例:.float 0F3.14,0F359.2E11常量编译控制伪操作6、.double语法格式:.double expr expr 说明:用于定义一个64位IEEE浮点数。举例:.double 0F2E1常量编译控制伪操作7、.word,.long,.int语法格式:op expr expr 说明:用于分配一段字内存单元.举例:.word 21,0 x110033 21,0 x110033常量编译控制伪操作8、.fill语 法 格 式:.fill repeat,size,value 说明:用于分配一段字内存单元
50、,用size长度value填充repeat次。举例:.fill 8,4,0 xFFFFFFFF 8,4,0 xFFFFFFFF常量编译控制伪操作9、.zero语法格式:.zerosize 说明:用于分配一段字节内存单元,用0填充内存。举例:.zero 400 400常量编译控制伪操作10、.space,.skip语法格式:opsize,value 说明:用于分配一段内存单元,用value初始化内存。举例:.space 10,0BFF 10,0BFF字符编译控制伪操作1、.equ,.set语法格式:opsymbol,expr 说明:用于为数字常量、基于寄存器的值和程序中的标号定义一个字符名称。举