资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,2008年10月23日,南京大学计算机系,*,嵌入式系统原理与开发,第,10,讲,南京大学计算机系 俞建新主讲,2008,年春季,第,5,章,ARM指令集,和汇编语言程序,本章主要介绍以下内容:,ARM,指令集的基本特点,与,Thumb,指令集的区别,与,x86,处理器的区别,ARM,指令格式,ARM,寻址方式,ARM,指令集分类详解,ARM,汇编语句格式和程序格式,ARM,汇编语言的指示符,ARM,汇编程序标准与规范,典型,ARM,汇编语言程序举例,2008年10月23日,2,南京大学计算机系,本讲主要参考文献,ARM,公司,英文资料:,ADS_AssemblerGuide_B.pdf,DDI0100E_ARM_ARM.pdf,中文图书,ARM,体系结构与编程,,清华大学出版社,嵌入式系统基础教程,,机械工业出版社,2008年10月23日,3,南京大学计算机系,嵌入式系统开发中汇编语言设计的意义,汇编语言程序设计更能充分发挥处理器的硬件特性,两个优势,操作系统移植需要编写几百行底层硬件的汇编语言程序,这是,C,语言不可取代的。,优化算法的时空效率,,C,语言的目标代码优化是编译器完成的,而汇编语言的目标代码优化是人工完成的。人是算法的创造者,也是编译器的设计者,人工优化比编译器质量高。,弱点,编程效率低,开发周期长,经济代价大。,2008年10月23日,4,南京大学计算机系,5.4 ARM,汇编语句格式和程序格式,两种,ARM,汇编语言格式,ARM,汇编语言程序格式主要有两种:,基于,ADS1.2,集成开发环境的汇编器格式,包括,SDT,在内,统称为,ADS,基于,Linux,的,GNU,汇编器格式,本讲前面部分介绍基于,ARM,公司,ADS,集成开发环境汇编器格式的汇编语言程序设计。,本讲后面将介绍基于,GNU,汇编器的,ARM,汇编语言程序编写方法。,2008年10月23日,5,南京大学计算机系,预定义寄存器名及内部变量名,ARM,汇编器中将几十个寄存器名称作为保留字预先给与了定义,这些预定义寄存器名都是大小写敏感的,它们都与具体的寄存器一一对应。参看下面的表格。,2008年10月23日,6,南京大学计算机系,ARM,公司,ADS,预定义的寄存器名一览表,预定义寄存器名,描述,r0-r15 and R0-R15,ARM,处理器的通用寄存器,a1-a4,入口参数,处理结果,暂存寄存器;,r0-r3,的同义词,v1-v8,变量寄存器,,r4-r11,sb,and SB,静态基址寄存器,,r9,sl,and SL,栈界限寄存器,,r10,fp,and FP,帧指针寄存器,,r11,ip,and IP,内部过程调用暂存寄存器,,r12,sp and SP,栈指针寄存器,,r13,2008年10月23日,7,南京大学计算机系,ARM,公司,ADS,预定义的寄存器名一览表(续),预定义寄存器名,描述,lr,and LR,连接寄存器,,r14,pc and PC,程序寄存器,,r15,cpsr,and CPSR,当前程序状态寄存器,spsr,and SPSR,保存的程序状态寄存器,f0-f7 and F0-F7,浮点数运算加速寄存器,s0-s31 and S0-S31,单精度向量浮点数运算寄存器,d0-d15 and D0-D15,双精度向量浮点数运算寄存器,p0-p15,协处理器,0-15,c0-c15,协处理器寄存器,0-15,2008年10月23日,8,南京大学计算机系,ARM,汇编语言程序的部分内部变量名清单,内部变量,描述,PC or.,当前指令地址,VAR or,内存区位置计数器的当前值,TRUE,逻辑值真,FALSE,逻辑值假,CONFIG,汇编器如果在汇编,ARM,指令,取值为,32,,如果汇编,Thumb,指令,取值,16,ENDIAN,如果汇编器是大端序,则取值,big,;如果是小端序,则取值,little,。,CPU,被选择的,CPU,名称。缺省值是,ARM7TDMI,。,ARCHITECTURE,该变量内容是被选择的,ARM,体系结构的名称。如:,3,3M,4T,CODESIZE,CONFIG,的同义词,2008年10月23日,9,南京大学计算机系,44BINIT.S,中使用的汇编语言部分内部变量名使用范例,GBLL THUMBCODE;,设置一个全局逻辑变量,CONFIG,=16;if,config,=16,这里表示处于,16,位编译方式,THUMBCODE SETL TRUE;,设置,THUMBCODE,为,true,CODE32;,转入,32,位编译模式,|;else,THUMBCODE SETL FALSE;,设置,THUMBCODE,为,false,THUMBCODE;if THUMBCODE=TRUE,CODE32;for start-up code for Thumb mode,;,转入,32,位编译方式,2008年10月23日,10,南京大学计算机系,5.4.1 ARM,汇编语言程序的语句格式,ARM,汇编语言程序的语句格式格式如下:,symbol instruction|directive|pseudo-instruction ;comment,对应的中文语句格式描述是:,符号,指令,|,指示符,|,伪指令,;,注释,语句格式中,花括号括起来的部分表示可以省略;竖线分隔的字段表示可以替换。,2008年10月23日,11,南京大学计算机系,ARM,汇编语言程序中的符号,ARM,汇编语句中的符号可以是指令地址或标号、变量、常量和局部标号,符号属性可以是程序相关的、寄存器相关的或者是绝对地址。,在符号中,有程序相关的指示符,例如:,DCB,、,DCD,等;有寄存器相关的指示符,例如:,MAP,、,SPACE,、,DCDO,等;还有绝对地址。绝对地址是范围在,2,32,-1,的整数常数,直接用来表示地址。,2008年10月23日,12,南京大学计算机系,符号命名和书写规则,ARM,符号的命名和书写有以下规则:,可以使用大小写字母,数字和下划线对,符号,实行命名。除本地行号外,名称不能以数字开头。符号是大小写字母敏感的。,如果符号使用了范围更大的字符集,则需要用,单竖线,将符号名括起来,以便编译器处理。,例如:,|.text|,和,|,Image$ZI$Limit,|,单竖线不属于符号。在两个单竖线之间不能使用单竖线,分号和新的文字行。,一个程序段中符号不能重名。,符号不能够与系统内部变量或者系统预定义的符号同名。例如:,a1 or R0,、,sp,、,cpsr,、,PC or.,、,VAR or,、,CONFIG,、,CPU,等等。,2008年10月23日,13,南京大学计算机系,符号命名和书写规则(续),符号在其作用范围内必须唯一。,当程序中的符号与指令助记符或者指示符同名时,用双竖线将符号括起来。如,|,buffe_a,|,,这时双竖线并不是符号的组成部分。,在,ARM,汇编语言程序中,所有符号必须在一行的最左边位置开始书写,即所谓的顶格书写,不允许包含空格或者制表符。,符号的字符序列中不能大小写字母相混杂。,2008年10月23日,14,南京大学计算机系,数字常量,ARM,汇编语言中使用到的常量可以是数字常量、字符常量、字符串常量和布尔常量。,数字常量有以下,3,种表示方式:,1,)十进制数,如:,535,,,246,。,2,)十六进制数,如:,0 x645,,,0 xff00,。,3,),n,进制数,格式为,n_XXX,,其中,n,表示,n,进制,从,2,9,,,XXX,是具体的数字。,例如:,8_3777,,,8_5237702,2008年10月23日,15,南京大学计算机系,字符常量,字符常量由一对单引号括起来,包括一个单字符或者标准,C,中的转义字符。,例如:,A,,,n,。,字符串常量由一对双引号以及由它括住的一组字符串组成,包括标准,C,中的转义字符。如果需要使用双引号或字符,$,,则必须用”和,$,代替。,例如执行语句:,strtwo,SETS“This is character of”,其编译结果是:字符串“,This is character of”,被赋值给,strtwo,变量。,2008年10月23日,16,南京大学计算机系,$,在汇编语句中的使用举例,GBLS add4ff,add4ff SETS ADD r4,r4,#0 xFF;set up add4ff,$add4ff.00;invoke add4ff,;this produces,;ADD r4,r4,#0 xFF00,;elaborate substitution,GBLS s1,GBLS s2,GBLS,fixup,GBLA count,count SETA 14,s1 SETS ,a$b$count,;s1 now has value a$b0000000E,s2 SETS ,abc,Fixup,SETS|xy$s2.z|;,fixup,now has value|,xyabcz,|,|,C$code,|MOV r4,#16;but the label here is,C$code,2008年10月23日,17,南京大学计算机系,逻辑值常量,布尔常量,TRUE,和,FALSE,在表达式中写为:,TRUE,,,FALSE,。,2008年10月23日,18,南京大学计算机系,表达式,ARM,汇编语言中的表达式由符号、数值、单目操作符、双目操作符以及括号组成。运算的优先级次序与标准,C,一样。,2008年10月23日,19,南京大学计算机系,字符串表达式,字符串由字符串常量、字符串变量、操作符以及括号组成。最大长度为,512,字节,最短,0,个字节。字符串表达式的组成元素有:字符串常量、字符串变量、操作符等。字符串常量由包含在双引号内的一系列字符组成。当在字符串中包含美元符号,$,或者引号”时,用,$,表示一个,$,,用”表示一个”。字符串变量用指示符,GBLS,(全局字符串)或者,LCLS,(局部字符串)声明,用,SETS,赋值。取值范围与字符表达式相同。,2008年10月23日,20,南京大学计算机系,ARM,汇编语言中的字符串操作符,操作符,功能,操作符,功能,LEN,返回字符串的长度,CHR,将,0255,之间整数变为单个字符,STR,将一个数字量变换为串,LEFT,返回字符串的左子串,RIGHT,返回字符串的右子串,CC,连接两个字符串,2008年10月23日,21,南京大学计算机系,数字表达式,数字表达式由数字常量、数字变量、操作符和括号组成。数字表达式表示的是一个,32,位数的整数,其取值范围为,02,32,-1,;当作为有符号数时,其取值范围为,-2,31,2,31,-1,。,汇编器对,-n,和,2,32,-n,不做区别,汇编时对关系运算符采用无符号数方式处理,这就意味着,0-1,是,FALSE,。,2008年10月23日,22,南京大学计算机系,逻辑表达式,逻辑表达式由逻辑常量、逻辑操作符、关系操作符以及括号组成。取值范围为,FALSE,和,TRUE,。,2008年10月23日,23,南京大学计算机系,地址标号,当符号代表地址时称为标号(,Label,)。,以数字开头的标号其作用范围是当前段(没有使用,ROUT,指示符时),这种标号又称为局部标号(,Local Label,)。,2008年10月23日,24,南京大学计算机系,三种类型标号,(,1,),PC,相关标号,(,2,)寄存器相关标号,(,3,)绝对地址,2008年10月23日,25,南京大学计算机系,PC,相关标号,PC,相关标号表示程序计数器加减一个数值常数后得到的地址值。常用来指明一个分支指令的目标地址,或者访问嵌入在代码段中的一个数据项。,具体标记方法是:在汇编语言程序指令的前面写入标号,或者在一个数据指示符前面写入标号。通常用,DCB,或者,DCD,等指示符定义。,2008年10月23日,26,南京大学计算机系,寄存器相关标号,寄存器标号表示指定寄存器的值加减一个数值常数后得到的地址值。常常用于访问位于数据段中的数据。通常用,MAP,或者,FIELD,等指示符定义。,2008年10月23日,27,南京大学计算机系,绝对地址,绝对地址是一个,32,位的无符号数字常量,可寻址范围是,02,31,-1,。使用它可以直接寻址整个地址空间。,2008年10月23日,28,南京大学计算机系,段内标号和段外标号,ARM,处理器的地址标号分为段内标号和段外标号。段内标号的地址值在汇编时确定,段外标号的地址值在连接时确定。,2008年10月23日,29,南京大学计算机系,程序相对寻址和寄存器相对寻址,在程序段中标号代表其所在位置与段首地址的偏移量,根据程序计数器和偏移量计算地址称为程序相对寻址。,在映像文件中定义的标号代表标号到映像首地址的偏移量。映像的首地址通常被赋予一个寄存器,根据该寄存器值与偏移量计算地址称为寄存器相对寻址。,2008年10月23日,30,南京大学计算机系,局部标号,ARM,汇编语言的宏常常使用局部标号。局部标号提供分支指令在汇编程序的局部范围内进行跳转,主要用途是汇编子程序中的循环和条件编码。它是一个,099,之间的数字,后面可以有选择地附带一个符号名称。,局部标号特别适用于宏。,2008年10月23日,31,南京大学计算机系,局部标号(续,1,),使用,ROUT,指示符可以限制局部标号的范围。只能在该局部标号的范围引用局部标号。如果在该范围的上下两个方向都没有匹配的标号,汇编器将给出一个错误信号并停止汇编。,局部标号语法格式如下:,nroutname,被引用的局部标号语法规则是:,%F|B A|T n,routname,2008年10月23日,32,南京大学计算机系,局部标号(续,2,),n,是局部标号的数字号。,routname,是当前局部范围的名称。,%,表示引用操作。,F,指示汇编器只向前搜索,B,指示汇编器只向后搜索,A,指示汇编器搜索宏的所有嵌套层次,T,指示汇编器搜索宏的当前层次,如果,F,和,B,都没有指定,则汇编器首先向前搜索,再向后搜索。如果,A,和,T,都没有指定,汇编器搜索从宏的当前层次到宏的最高层次,比当前层次低的宏不再搜索。,2008年10月23日,33,南京大学计算机系,5.5 ARM,汇编语言程序的指示符,ARM,汇编语言源程序中语句由指令、指示符和宏指令组成。,在,ARM,中将,directive,称做指示符,ARM,的指示符指令相当于,x86,的伪指令,在,ARM,中,pseudo-instruction,被称为伪指令,ARM,指令集中只有,4,条伪指令,而宏指令则是通过指示符定义的。,使用,MACRO,和,MEND,指示符,2008年10月23日,34,南京大学计算机系,ARM,汇编语言指示符的特点,ARM,指示符语句与,ARM,机器指令不存在一一对应的关系,它指示汇编器在汇编目标代码时进行变量定义、存储单元分配等操作。,ARM,指示符大致可以分成,6,种类型,分别是:符号定义、数据定义、汇编控制、框架控制、信息报告和杂项。,2008年10月23日,35,南京大学计算机系,5.5.1,符号定义指示符,符号定义,(Symbol definition),指示符用于定义,ARM,汇编程序中的变量,对变量进行赋值以及定义寄存器名称。包括以下指示符:,GBLA,,,GBLL,及,GBLS,声明全局变量;,LCLA,,,LCLL,及,LCLS,声明局部变量;,SETA,,,SETL,及,SETS,给变量赋值;,RLIST,为通用寄存器列表定义名称;,CN,为协处理器的寄存器定义名称;,CP,为协处理器定义名称;,DN,及,SN,为,VFP,的寄存器定义名称;,FN,为,FPA,的浮点寄存器定义名称。,2008年10月23日,36,南京大学计算机系,5.5.2,数据定义指示符,数据定义,(Data definition),指示符包括以下的指示符:,LTORG,声明一个数据缓冲池,(literal pool),的开始;,MAP,定义一个结构化的内存表,(storage map),的首地址;,FIELD,定义结构化的内存表中的一个数据域,(field),;,SPACE,分配一块内存单元,并用,0,初始化;,DCB,分配一段字节的内存单元,并用指定的数据初始化;,DCD,及,DCDU,分配一段字的内存单元,并用指定的数据初始化;,DCDO,分配一段字的内存单元,并将单元的内容初始化成该单元相对于静态基值寄存器的偏移量。,2008年10月23日,37,南京大学计算机系,数据定义指示符(续),DCFD,及,DCFDU,分配一段双字的内存单元,并用双精度的浮点数据初始化。,DCFS,及,DCFSU,分配一段字的内存单元,并用单精度的浮点数据初始化。,DCI,分配一段字节的内存单元,用指定的数据初始化,指定内存单元中存放的是代码,而不是数据。,DCQ,及,DCQU,分配一段双字的内存单元,并用,64,位的整数数据初始化。,DCW,及,DCWU,分配一段半字的内存单元,并用指定的数据初始化。,DATA,在代码段中使用数据。现已不再使用,仅用于保持向前兼容。,2008年10月23日,38,南京大学计算机系,LTORG,指示符,LTORG,指示符要求汇编器立即安排一个数据缓冲池(文字池)。,语法:,LTORG,使用说明:通常,ARM,汇编器把数据缓冲池放在代码段的最后面,即下一个代码段开始之前,或者,END,指示符之前。,当程序中使用,LDMFD,之类的指令时,数据缓冲池可能越界。这时可以使用,LTORG,指示符定义数据缓冲池。以防止越界发生。通常,大的代码段可以使用多个数据缓冲池。,LTORG,指示符通常放在无条件跳转指令之后。或者子程序返回之后,这样处理器就不会错误地把数据缓冲池中的数据当作指令来执行。,2008年10月23日,39,南京大学计算机系,LTORG,指示符使用举例,AREA EXP_1,CODE,READONLY,STARTBLFUNC1,FUNC1,;CODE,LDR R1,=55555555,;,产生形如,LDR R1,PC,#offset to Literal Pool,的指令,;CODE,MOV PC,LR;,子程序结束,LTORG;,定义数据缓冲池,&55555555,DATASPACE 46;,从当前位置开始分配,46,字节,END;,默认的数据缓冲池为空,2008年10月23日,40,南京大学计算机系,使用,MAP,和,FIELD,描述数据结构,ADS,编译器使用,MAP,和,FIELD,两个指示符描述数据结构。,MAP,定义了数据结构的起始地址。,FIELD,用来定义数据结构中的字段,2008年10月23日,41,南京大学计算机系,MAP,指示符,是,MAP,的同义词,MAP,语法,MAP,expr,base-register,其中:,expr,为数字表达式或者是程序中的标号。,当指令中没有,base-register,时,,expr,即为结构化内存表的首地址。此时内存表的位置计数器,VAR,设置成该地址值。,当,expr,为程序中的标号,该标号必须是已经定义过的。,base-register,为一个寄存器。当指令中包含这一项时,结构化内存表(数据结构)的首地址为,expr,和,base-register,寄存器的和。,2008年10月23日,42,南京大学计算机系,MAP,指示符使用举例,下面是,MAP,指示符汇编语句举例,MAP 0 xA0FF,R8;,数据结构首地址为,R8+0 xA0FF,;,也就是,VAR,的值成为,R8+0 xA0FF,MAP 0 xC12305;,数据结构起始位置是,0 xC12305,MAP readdata+86;,数据结构起始位置是,readdata+86,;,readdata,标号已经定义过了,MAP 0,R7;,数据结构起始位置是,R7,中的数据,MAP 0 x1FF,R6;,数据结构起始位置是,R7,中的数据,;,加上,0 x1FF,2008年10月23日,43,南京大学计算机系,FIELD,指示符,#,是,FIELD,的同义词,FIELD,语法,label FIELD,expr,其中:,label,为可选项。当指令中包含,label,时,标号,label,的值为当前内存表位置计数器,VAR,的值。汇编编译器执行完此条,FIELD,指示指令后,内存表位置计数器的值将加上,expr,。,expr,表示本字段(数据项)在内存表中所占的字节数。,2008年10月23日,44,南京大学计算机系,MAP,和,FIELD,指示符使用说明,FIELD,指示符说明一个数据项所需要的内存空间,并且为这个数据项提供一个标号。,MAP,指示符中的,base-register,寄存器对于其后所有的,FIELD,指示符定义的数据项是默认使用的,直至遇到新的包含,base-register,寄存器的,MAP,指示符。,2008年10月23日,45,南京大学计算机系,MAP,和,FIELD,联合使用举例,startofdata,EQU0 x0100 ;,MAP,startofdata,int_a,field 4,int_b,field 4,str_one,field 64,k_array,field 128,bit_mask,field 4,本例中数据结构的起始位置映射到固定(绝对)地址,0 x0100,,然后为各个字段分配空间。也可以用,LDR,和,STR,之类的指令对结构体中的字段进行操作。例如使用下面的语句:,LDRR4,int_a,2008年10月23日,46,南京大学计算机系,MAP,和,FIELD,联合使用举例(续,1,),;,本代码清单是上一个幻灯片的等效代码,startofdata,EQU0 x0100,startofdata,int_a,#4,int_b,#4,str_one,#64,k_array,#128,bit_mask,#4,2008年10月23日,47,南京大学计算机系,MAP,和,FIELD,联合使用举例(续,2,),对上述,MAP,和,FIELD,联合使用举例代码中的,int_a,赋值的代码清单如下:,MOV R0,#20,LDR R1,=,int_a,;,也可以使用语句,LDR R1,int_a,STR R0,R1,2008年10月23日,48,南京大学计算机系,用,EQU,指示符完成,MAP,和,FIELD,联合使用举例代码的等效操作,实际上,使用,MAP,和,FIELD,描述的数据结构也可以使用,EQU,描述。参见下面的代码清单。,startofdata,EQU0 x0100,int_a,EQU,startofdata,int_b,EQUint_a+4,str_one,EQUint_b+4,k_array,EQUstr_one+64,bit_mask,EQUk_array+128,;,这种,EQU,指示符的代码结构修改繁琐,不推荐使用,2008年10月23日,49,南京大学计算机系,SPACE,指示符,SPACE,用于分配一块内存单元,并且用,0,初始化。,%,是,SPACE,的同义词,语法:,label MAP,expr,其中:,label,是可选项;,expr,是本指示符分配的内存字节数。,示例,Pro_data,SPACE 1290 ;,分配,1290,个字节内存单元,;,并且将该存储区初始化为,0,2008年10月23日,50,南京大学计算机系,相对地址,相对地址有两种:,一种是以寄存器作为基地址的相对偏移,可以分为两类,基于相对地址的内存表,基于寄存器的内存表,另外一种是基于程序的相对偏移,2008年10月23日,51,南京大学计算机系,基于寄存器的相对偏移,;,基于相对地址的内存表示代码如下,MAP 0,int_a,FIELD 4 ;,为,int_a,分配,4,个字节,int_b,FIELD 4 ;,为,int_b,分配,4,个字节,str_one,FIELD 64 ;,为,str_one,分配,64,个字节,k_array,FIELD 128 ;,为,k_array,分配,128,个字节,bit_mask,FIELD 4 ;,为,bit_mask,分配,4,个字节,;,这种情况下的基址寄存器是不固定的,2008年10月23日,52,南京大学计算机系,程序相对偏移,以程序偏移地址作为基地址相对以寄存器为基地址要简单得多。首先要为数据结构申请存储空间,然后将申请的空间首部地址作为基地址。,代码如下面的幻灯片所示:,2008年10月23日,53,南京大学计算机系,程序相对偏移(续),;,使用程序相对偏移为基地址,s_label,SPACE 280,;,申请空间用来存放数据结构,MAP,s_label,;,将分配空间的起始地址作为基地址,int_a,FIELD 4,int_b,FIELD 4,strone,FIELD 64,k_array,FIELD 128,bit_mask,FIELD 4 ;,这种情况下基地址由编译器安排,2008年10月23日,54,南京大学计算机系,5.5.3,汇编控制指示符,汇编控制,(Assembly control),指示符包括下面的指示符:,IF,,,ELSE,及,ENDIF,汇编或者不汇编一段源代码,WHILE,及,WEND,条件重复汇编相同的一段源代码,MACRO,及,MEND,标识宏定义开始与结束,MEXIT,用于从宏跳转出去,2008年10月23日,55,南京大学计算机系,5.5.4,信息报告指示符,信息报告,(Reporting),指示符包括下列指示符:,ASSERT,在汇编编译器对汇编程序的第二趟扫描中,如果其中的,ASSERTION,中条件不成立,,ASSERT,伪操作将报告该错误信息。,INFO,支持第一二趟汇编扫描时报告诊断信息。,OPT,TTL,及,SUBT,2008年10月23日,56,南京大学计算机系,5.5.5,其他指示符,这些杂类的指示符包括:,ALIGN,AREA,CODE16,及,CODE32,END,ENTRY,EQU,EXPORT,或,GLOBAL,2008年10月23日,57,南京大学计算机系,其他的指示符(续),EXTERN,GET,或,INCLUDE,IMPORT,INCBIN,KEEP,NOFP,REQUIRE,REQUIRE8,及,PRESERVE8,RN,ROUT,2008年10月23日,58,南京大学计算机系,5.5.5.1 AREA,AREA,指示符用于定义一个代码段或者数据段。,语法格式,AREA,sectionname,,,attr,,,attr,.,其中:,sectionname,为所定义的代码段或者数据段的名称。如果该名称是以数字开头的,则该名称必须用“”括起来,如,1_datasec,。,还有一些代码段具有约定的名称,如,.text,表示,C,语言编译器产生的代码段或者是与,C,语言库相关的代码段。,Attr,是该代码段,(,或者程序段,),的属性。,在,AREA,指示符中,各属性间用逗号隔开。,2008年10月23日,59,南京大学计算机系,AREA,的属性,下面列举主要的属性:,ALIGN=expression,。,默认的情况下,,ELF,的代码段和数据段是,4,字节对齐的。,Expression,可以取,0,31,的数值,相应的对齐方式为,(2,expression,),字节对齐。如,expression=3,时为,8,字节对齐。,ASSOC=section,。,指定与本段相关,的,ELF,段。任何时候连接,section,段也必须包括,sectionname,段。,CODE,定义代码段。默认属性为,READONLY,。,COMDEF,定义一个通用的段。该段可以包含代码或者数据。在个源文件中,同名的,COMDEF,段必须相同。,2008年10月23日,60,南京大学计算机系,AREA,的属性(续),COMMON,定义一个通用的段。该段不包含任何用户代码和数据,连接器将其初始化为,0,。各源文件中同名的,COMMON,段公用同样的内存单元,连接器为起分配合适的尺寸。,DATA,定义数据段。默认属性为,READWRITE,。,NOINIT,指定本数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将个内存单元值初始化为,0,。,READONLY,指定本段为只读,代码段的默认属性为,READONLY,。,READWRITE,指定本段为可读可写,数据段的默认属性为,READWRITE,。,2008年10月23日,61,南京大学计算机系,AREA,指示符举例,举例,下面的指示符定义了一个代码段,代码段的名称为,Mainpro,,,属性为,READONLY,。,AREA,Mainpro,CODE,READONLY,;code segment,2008年10月23日,62,南京大学计算机系,5.5.5.2 EQU,EQU,指示符为数字常量、基于寄存器的值和程序中的标号,(,基于,PC,的值,),定义一个字符名称。,*是,EQU,的同义词。,语法格式,name EQU,expr,type,其中:,expr,为基于寄存器的地址值、程序中的标号、,32,位的地址常量或者,32,位的常量。,name,为,EQU,指示符为,expr,定义的字符名称。,type,当,expr,为,32,位常量时,可以使用,type,指示,expr,表示的数据的类型。,2008年10月23日,63,南京大学计算机系,EQU,(,续),type,有下面,3,种取值,:,CODE16,CODE32,DATA,使用说明,EQU,指示符的作用类似于,C,语言中的,#define,,,用于为一个常量定义字符名称。,示例,abcd,EQU 2 ;,定义,abcd,符号的值为,2,abcd,EQU label+16;,定义,abcd,符号的值,(label+16),addr1 EQU 0 xlC,CODE32;,定义,addr1,符号值为,;,绝对地址值,0 xlC,,,而且该处为,ARM,指令。,2008年10月23日,64,南京大学计算机系,5.5.5.3 ENTRY,ENTRY,指示符指定程序的入口点,语法格式,ENTRY,使用说明,一个程序,(,可以包含多个源文件,),中至少要有一个,ENTRY(,可以有多个,ENTRY),,,但一个源文件中最多只能有一个,ENTRY(,可以没有,ENTRY),。,示例,AREA example,CODE,READONLY,ENTRY ;,应用程序的入口点,2008年10月23日,65,南京大学计算机系,5.5.5.4 CODE16和CODE32,CODE16,指示符告诉汇编编译器后面的指令序列为,16,位的,Thumb,指令。,CODE32,指示符告诉汇编编译器后面的指令序列为,32,位的,ARM,指令。,语法格式,CODE16,CODE32,使用说明,当汇编源程序中同时包含,ARM,指令和,Thumb,指令时,使用,CODE16,指示符告诉汇编编译器后面的指令序列为,16,位的,Thumb,指令;使用,CODE32,指示符告诉汇编编译器后面的指令序列为,32,位的,ARM,指令。但是,,CODE16,指示符和,CODE32,指示符只是告诉编译器后面指令的类型,该指示符本身并不进行程序状态的切换。,2008年10月23日,66,南京大学计算机系,CODE16/CODE32,举例,在下面的例子中,程序先在,ARM,状态下执行,然后通过,BX,指令切换到,Thumb,状态,并跳转到相应的,Thumb,指令处执行。在,Thumb,程序入口处用,CODE16,指示符标识下面的指令为,Thumb,指令。参看下面的指令段:,.,AREA,ChangeState,CODE,READONLY,CODE32;,指示下面的指令为,ARM,指令,LDR r0,=start+1,BX r0 ;,切换到,Thumb,,并跳转到,start,处执行,CODE16 ;,指示下面的指令为,Thumb,指令,startMOV r1,#10,2008年10月23日,67,南京大学计算机系,5.5.5.5 END,END,指示符告诉编译器已经到了源程序结尾。,语法格式:,END,使用说明:,每一个汇编源程序都包含,END,指示符,以告诉本源程序的结束。,示例:,AREA example CODE,,,READONLY,END,2008年10月23日,68,南京大学计算机系,5.5.5.6 ALIGN,ALIGN,指示符通过添加补丁字节使当前位置满足一定的对齐方式。,语法格式,ALIGN,expr,,,offset,其中,,expr,为数字表达式,用于指定对齐方式。可能的取值为,2,的次幂,如,1,、,2,、,4,、,8,等。如果指示符中没有指定,expr,,,则当前位置对齐到下一个字边界处。,offset,为数字表达式。当前位置对齐到下面形式的地址处:,offset+n*,expr,。,2008年10月23日,69,南京大学计算机系,ALIGN,(,续,1,),使用说明,下面的情况中,需要特定的地址对齐方式:,Thumb,的宏指令,ADR,要求地址是字对齐的,而,Thumb,代码中地址标号可能不是字对齐的。这时就要使用指示符,ALIGN 4,使,Thumb,代码中的地址标号字对齐。,由于有些,ARM,处理器的,CACHE,采用了其他对齐方式,如,16,字节的对齐方式,这时使用,ALIGN,指示符指定合适的对齐方式可以充分发挥该,CACHE,的性能优势。,LDRD,及,STRD,指令要求内存单元是,8,字节对齐的。这样在为这两个指令分配的内存单元前要使用,ALIGN 8,实现,8,字节对齐方式。,地址标号通常自身没有对齐要求。而在,ARM,代码中要求地址标号是字对齐的,在,Thumb,代码中要求字节对齐。这样需要使用合适的,ALIGN,指示符来调整对齐方式。,2008年10月23日,70,南京大学计算机系,5.5.5.7 EXPORT及GLOBAL,EXPRORT,声明一个符号可以被其他文件引用。相当于声明了一个全局变量。,GLOBAL,是,EXPORT,的同义词。,语法格式,EXPORT symbol WEAK,其中,,symbol,为声明的符号名称,大小写敏感。,WEAK,选项声明其他的同名符号优先于本符号被引用。,使用说明,使用,EXPORT,指示符声明一个源文件中的符号,使得该符号可以被其他源文件引用。,示例,AREA Example,,,CODE,,,READONLY,EXPORT,Do_Add,;,函数名称,DoAdd,可以被引用,2008年10月23日,71,南京大学计算机系,5.5.5.8 IMPORT,IMPORT,指示符告诉编译器当前的符号不是在本源文件中定义的,而是在其他源文件中定义的,在本源文件中可能引用该符号,而且不论本源文件是否实际引用该符号,该符号都将被加入到本源文件的符号表中。,语法格式,IMPORT symbol WEAK,其中:,symbol,为声明的符号的名称。它是区分大小写的。,WEAK,指定这个选项后,如果,symbol,在所有的源文件中都没有被定义,编译器也不会产生任何错误信息,同时编译器也不会到当前没有被,INCLUDE,进来的库中去查找该符号。,2008年10月23日,72,南京大学计算机系,IMPORT,(,续),使用说明,使用,IMPORT,指示符声明一个符号是在其他源文件中定义的。如果连接器在连接处理时不能解析该符号,而,IMPORT,指示符中没有指定,WEAK,选项,则连接器将会报告错误。如果连接器在连接处理时不能解析该符号,而,IMPORT,指示符中指定了,WEAK,选项,则连接器将不会报告错误,而是进行下面的操作:,如果该符号被
展开阅读全文