1、2024/4/17 周三第四章 ARM汇编程序设计2024/4/17 周三 了解与熟悉了解与熟悉ADSADS下的伪操作和宏指令以及下的伪操作和宏指令以及它的应用它的应用 了解与熟悉了解与熟悉GNUGNU下的伪操作和宏指令以及下的伪操作和宏指令以及它的应用它的应用 熟悉熟悉ARM ATPCSARM ATPCS 能够利用汇编语言进行简单的程序设计能够利用汇编语言进行简单的程序设计 2024/4/17 周三1.1.伪指令、伪操作和宏指令概念伪指令、伪操作和宏指令概念 伪指令伪指令是汇编语言程序里的特殊指令助记符,是汇编语言程序里的特殊指令助记符,在汇编时被合适的机器指令替代。在汇编时被合适的机器指令
2、替代。伪操作伪操作为汇编程序所用,在源程序进行汇编为汇编程序所用,在源程序进行汇编时由汇编程序处理,只在汇编过程起作用,不参与时由汇编程序处理,只在汇编过程起作用,不参与程序运行。程序运行。4.1.4.1.汇编伪指令和宏指令汇编伪指令和宏指令2024/4/17 周三 宏指令宏指令通过伪操作定义的一段独立的代码。在调用它通过伪操作定义的一段独立的代码。在调用它时将宏体插入到源程序中。时将宏体插入到源程序中。也就是常说的宏也就是常说的宏。说明:说明:所有的伪指令、伪操作和宏指令,均与具体的开所有的伪指令、伪操作和宏指令,均与具体的开发工具中的编译器有关,当前主要采用发工具中的编译器有关,当前主要采
3、用ARM公司的公司的“ADS/SDT IDE”开发工具,所以后面的讨论,均是基于开发工具,所以后面的讨论,均是基于ARM公司的开发工具。公司的开发工具。2024/4/17 周三2.ARM2.ARM汇编伪指令汇编伪指令 ARM伪指令不属于伪指令不属于ARM指令集中的指令,是为了编指令集中的指令,是为了编程方便而定义的。伪指令可以像其它程方便而定义的。伪指令可以像其它ARM指令一样使用,指令一样使用,但在编译时这些指令将被等效的但在编译时这些指令将被等效的ARM指令代替。指令代替。ARM伪指令有四条,分别是:伪指令有四条,分别是:ADR:小范围的地址读取伪指令。:小范围的地址读取伪指令。ADRL:
4、中等范围的地址读取伪指令。:中等范围的地址读取伪指令。LDR:大范围的地址读取伪指令。:大范围的地址读取伪指令。NOP:空操作伪指令。:空操作伪指令。2024/4/17 周三(1)ADR小范围的地址读取小范围的地址读取 ADR伪指令功能:伪指令功能:将基于将基于PC相对偏移的地址值或基于寄相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。存器相对偏移的地址值读取到寄存器中。ADR伪指令功能的实现方法:伪指令功能的实现方法:在汇编编译器编译源程序在汇编编译器编译源程序时,时,ADR伪指令被编译器替换成一条合适的指令。通常,编伪指令被编译器替换成一条合适的指令。通常,编译器用一条译器用一
5、条ADD指令或指令或SUB指令来实现此指令来实现此ADR伪指令的功能,伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。若不能用一条指令实现,则产生错误,编译失败。语法格式:语法格式:ADRcond register,expr其中:其中:register:加载的目标寄存器。:加载的目标寄存器。expr:地址表达式。取值范围是参考:地址表达式。取值范围是参考P2122024/4/17 周三例例1:(0 x20)ADR R1,Delay Delay(0 x64)MOV R0,R14 使用使用ADR将程序标号将程序标号Delay所表示的地址存入所表示的地址存入R1。编译后的反汇编代码:编译后
6、的反汇编代码:ADD R1,PC,#0 x3C MOV R0,R14 PC+0 x3C=0 x20+0 x08+0 x3C=0 x642024/4/17 周三例例2:查表:查表 ADR R0,D_TAB ;加载转换表地址加载转换表地址 LDRB R1,R0,R2 ;使用使用R2作为参数,进行查表作为参数,进行查表 D_TAB DCB 0 xC0,0 xF9,0 xA4,0 xB0,0 x99,0 x922024/4/17 周三(2)ADRL中等范围的地址读取中等范围的地址读取ADRL伪指令功能:伪指令功能:将基于将基于PC相对偏移的地址值或基于寄相对偏移的地址值或基于寄存器相对偏移的地址值读取
7、到寄存器中,比存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读伪指令可以读取更大范围的地址。取更大范围的地址。ADRL伪指令功能实现方法:伪指令功能实现方法:在汇编编译器编译源程序时,在汇编编译器编译源程序时,ADRL被编译器替换成两条合适的指令。若不能用两条指令实被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。现,则产生错误,编译失败。语法格式:语法格式:ADRLcond register,expr其中:其中:register:加载的目标寄存器。:加载的目标寄存器。expr:地址表达式。取值范围参考:地址表达式。取值范围参考P2122024/4/17 周三例
8、例3:(0 x20)ADRL R1,Delay Delay(0 x64)MOV R0,R14 使用使用ADRL将程序标号将程序标号Delay所表示的地址存入所表示的地址存入R1。编译后的反汇编代码:编译后的反汇编代码:ADD R1,PC,#0 x3CADD R1,R1,#0 MOV R0,R14 ADRL ADRL伪指令被汇编成两伪指令被汇编成两条指令,尽管第条指令,尽管第2 2条指令并没条指令并没有意义。有意义。2024/4/17 周三(3)LDR 大范围的地址读取大范围的地址读取LDR伪指令功能:伪指令功能:用于加载用于加载32位立即数或一个位立即数或一个地址值到指定的寄存器。地址值到指定
9、的寄存器。LDR伪指令功能实现方法:伪指令功能实现方法:在汇编编译源程序在汇编编译源程序时,时,LDR伪指令被编译器替换成一条合适的指令。伪指令被编译器替换成一条合适的指令。若若加载的常数未超过加载的常数未超过MOV或或MVN的范围,则使的范围,则使用用MOV或或MVN指令代替该指令代替该LDR伪指令;伪指令;否则否则汇编器将常量放入文字池,并使用一条程汇编器将常量放入文字池,并使用一条程序相对偏移的序相对偏移的LDR指令从文字池读出常量。指令从文字池读出常量。2024/4/17 周三 语法格式:语法格式:LDRcond register,=expr其中:其中:Register:加载的目标寄存
10、器。:加载的目标寄存器。expr:32位常量或地址表达式。位常量或地址表达式。2024/4/17 周三例例4:(0 x060)LDR R1,=Delay Delay(0 x102)MOV R0,R14 使用使用LDR将程序标号将程序标号Delay所表示的地址存入所表示的地址存入R1。编译后的反汇编代码:编译后的反汇编代码:LDR R1,stack Delay MOV R0,R14 LTORGstack DCD 0 x102 LDR伪指令被汇编成一条伪指令被汇编成一条LDR指令指令,并在文字池中定义一个常量并在文字池中定义一个常量,该常量为标号该常量为标号Delay的地址。的地址。2024/4/
11、17 周三注意:注意:从指令位置到文字池的偏移量必须小于从指令位置到文字池的偏移量必须小于4KB。与与ARM指令的指令的LDR的区别:伪指令的区别:伪指令LDR的参数有的参数有“=”号。号。2024/4/17 周三(4)NOP空操作伪指令空操作伪指令NOP伪指令功能实现方法:伪指令功能实现方法:在汇编时将被替代成在汇编时将被替代成ARM中的空操作,比如可能是中的空操作,比如可能是“MOV R0,R0”指令等。指令等。用途:用途:NOP可用于延时操作。可用于延时操作。语法格式:语法格式:NOP例:延时子程序例:延时子程序 Delay NOP ;空操作空操作 NOP NOP SUBS R1,R1,
12、#1 ;循环次数减循环次数减1 BNE Delay MOV PC,LR2024/4/17 周三3.ARM3.ARM汇编伪操作汇编伪操作ADS编译环境下的伪操作可分为以下几类:编译环境下的伪操作可分为以下几类:符号定义符号定义(Symbol Definition)伪操作)伪操作 数据定义数据定义(Data Definition)伪操作)伪操作 汇编控制汇编控制(Assembly Control)伪操作)伪操作 其它其它(Miscellaneous)伪操作)伪操作 2024/4/17 周三(1)符号定义伪操作符号定义伪操作 vGBLA,GBLL,GBLS:声明全局变量。:声明全局变量。vLCLA,
13、LCLL,LCLS:声明局部变量。:声明局部变量。vSETA,SETL,SETS:给变量赋值。:给变量赋值。vRLIST:为通用寄存器列表定义名称。:为通用寄存器列表定义名称。2024/4/17 周三(2)数据定义伪操作数据定义伪操作LTORG:声明一个数据缓冲池的开始:声明一个数据缓冲池的开始SPACE:分配一块字节内存单元,并用:分配一块字节内存单元,并用0初始化初始化DCB:分配一段字节内存单元,并初始化:分配一段字节内存单元,并初始化DCD、DCDU:分配一段字内存单元,并初始化:分配一段字内存单元,并初始化MAP:定义一个结构化的内存表的首地址:定义一个结构化的内存表的首地址FIEL
14、D:定义结构化内存表中的一个数据域:定义结构化内存表中的一个数据域 2024/4/17 周三 MAPMAP、FIELDFIELD、SPACEMAP 0 x100MAP 0 x100,R0 R0;定义结构化内存表首地址的值为;定义结构化内存表首地址的值为0 x1000 x100R0R0A FIELD 16 A FIELD 16;定义;定义A A的长度为的长度为1616字节,位置为字节,位置为0 x110+R0 0 x110+R0 LTORG ;定义数据缓冲池定义数据缓冲池&0 x8000Data SPACE 4200;从当前位置开始分配从当前位置开始分配4200字节的内存单字节的内存单元,并初始
15、化为元,并初始化为0。2024/4/17 周三LTORG用于声明一个数据缓冲池(文字池)的开始。用于声明一个数据缓冲池(文字池)的开始。语法格式:语法格式:LTORG例:例:start BL func;func LDR R1,=0 x8000 ;子程序子程序 MOV PC,LR ;子程序返回子程序返回 LTORG ;定义数据缓冲池定义数据缓冲池&0 x8000Data SPACE 4200 ;从当前位置开始分配从当前位置开始分配4200字节的内字节的内 存单元,并初始化为存单元,并初始化为0。END 默认数据缓冲池为空默认数据缓冲池为空2024/4/17 周三注意:注意:LTORG伪操作通常放
16、在无条件跳转指令之后,伪操作通常放在无条件跳转指令之后,或者子程序返回指令之后,这样处理器不会错误地或者子程序返回指令之后,这样处理器不会错误地将数据缓冲池中的数据当作指令来执行。将数据缓冲池中的数据当作指令来执行。通常通常ARM汇编编译器把数据缓冲池放在代码段汇编编译器把数据缓冲池放在代码段的最后面,即下一个代码段开始之前,或者的最后面,即下一个代码段开始之前,或者END伪伪操作之前。操作之前。2024/4/17 周三 DCB也可以用符号也可以用符号”=”表示表示用于定义并且初始化一个或者多个字节的内存区域。用于定义并且初始化一个或者多个字节的内存区域。语法格式:语法格式:label DCB
17、 expr,expr或或 label =expr,expr其中其中expr表示:表示:-128到到255之间的一个数值常量或者表达式。之间的一个数值常量或者表达式。一个字符串。一个字符串。注意:注意:当当DCB后面紧跟一个指令时,可能需要使用后面紧跟一个指令时,可能需要使用ALIGN确保指令是字对齐的。确保指令是字对齐的。2024/4/17 周三例:例:short DCB 1 ;为为short分配了一个字节分配了一个字节,并初始化为并初始化为1。string DCB “string”,0 ;构造一个以构造一个以0 结尾的字符串结尾的字符串 2024/4/17 周三DCD、DCDU分配一段字内存
18、单元分配一段字内存单元(1)DCD 分配一段字对齐的内存单元分配一段字对齐的内存单元用于分配一段字对齐的内存单元,并初始化。用于分配一段字对齐的内存单元,并初始化。DCD也可以用符号也可以用符号”&”表示表示语法格式:语法格式:label DCD expr,expr或或 label&expr,expr 其中:其中:expr:数字表达式或程序中的标号。:数字表达式或程序中的标号。注意:注意:DCD伪操作可能在分配的第一个内存单元前插入填补字节以保伪操作可能在分配的第一个内存单元前插入填补字节以保证分配的内存是字对齐的。证分配的内存是字对齐的。2024/4/17 周三例:例:data1 DCD 2
19、,4,6 ;为为data1分配三个字分配三个字,内容初始化为内容初始化为2,4,6 data2 DCD label+4 ;初始化初始化data2为为label+4对应的地址对应的地址 (2)DCDU 分配一段字非严格对齐的内存单元分配一段字非严格对齐的内存单元DCDU与与DCD的不同之处在于的不同之处在于DCDU分配的内存单元并分配的内存单元并不严格字对齐。不严格字对齐。2024/4/17 周三(3)汇编控制伪操作)汇编控制伪操作IF,ELSE及及ENDIF:有条件选择汇编:有条件选择汇编WHILE及及WEND:有条件循环(重复)汇编:有条件循环(重复)汇编MACRO,MEND及及MEXIT:
20、宏定义汇编:宏定义汇编2024/4/17 周三(4)其它伪操作)其它伪操作AREA:定义一个代码段或数据段定义一个代码段或数据段 CODE16、CODE32:告诉编译器后面的指令序列位数告诉编译器后面的指令序列位数 ENTRY:指定程序的入口点指定程序的入口点 ALIGN:将当前的位置以某种形式对齐将当前的位置以某种形式对齐 END:源程序结尾源程序结尾 EQU:为数字常量、基于寄存器的值和程序中的标号定义一为数字常量、基于寄存器的值和程序中的标号定义一个字符名称。个字符名称。2024/4/17 周三 EXPORT、GLOBAL:声明源文件中的符号可以被其他源文声明源文件中的符号可以被其他源文
21、件引用件引用 IMPORT、EXTERN:声明某符号是在其他源文件中定义的声明某符号是在其他源文件中定义的 GET、INCLUDE:将一个源文件包含到当前源文件中,并将将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。被包含的文件在其当前位置进行汇编处理。INCBIN:将一个文件包含到当前源文件中,而被包含的文件将一个文件包含到当前源文件中,而被包含的文件不进行汇编处理不进行汇编处理2024/4/17 周三1)AREA用于定义一个代码段或是数据段。用于定义一个代码段或是数据段。语法格式:语法格式:AREA sectionname,attr,attr 其中:其中:sect
22、ionname:为所定义的段的名称。:为所定义的段的名称。attr:该段的属性。具有的属性为:该段的属性。具有的属性为:CODE:定义代码段。定义代码段。DATA:定义数据段。定义数据段。READONLY:指定本段为只读指定本段为只读,代码段的默认属性。代码段的默认属性。READWRITE:指定本段为可读可写指定本段为可读可写,数据段的默认数据段的默认属性。属性。2024/4/17 周三ALIGN:指定段的对齐方式为指定段的对齐方式为2expression。expression的取值为的取值为031。COMMON:指定一个通用段。该段不包含任指定一个通用段。该段不包含任何用户代码和数据。何用户
23、代码和数据。NOINIT:指定此数据段仅仅保留了内存单元,指定此数据段仅仅保留了内存单元,而没有将各初始值写入内存单元,或者将各个而没有将各初始值写入内存单元,或者将各个内存单元值初始化为内存单元值初始化为0。注意:注意:一个大的程序可包含多个代码段和数据一个大的程序可包含多个代码段和数据段。一个汇编程序至少包含一个代码段。段。一个汇编程序至少包含一个代码段。2024/4/17 周三2)CODE16和和CODE32CODE16告诉汇编编译器后面的指令序列为告诉汇编编译器后面的指令序列为16位的位的Thumb指令。指令。CODE32告诉汇编编译器后面的指令序列为告诉汇编编译器后面的指令序列为32
24、位的位的ARM指令。指令。语法格式:语法格式:CODE16 CODE32 注意:注意:CODE16和和CODE32只是告诉编译器后面指令只是告诉编译器后面指令的类型,该伪操作本身不进行程序状态的切换。的类型,该伪操作本身不进行程序状态的切换。2024/4/17 周三例:例:AREA ChangeState,CODE,READONLY ENTRY CODE32 ;下面为下面为32位位ARM指令指令 LDR R0,=start+1 BX R0 CODE16 ;下面为下面为16位位Thumb指令指令start MOV R1,#10 .END;切换到切换到Thumb状态,并跳转到状态,并跳转到star
25、t处执行处执行2024/4/17 周三3)ENTRY指定程序的入口点。指定程序的入口点。语法格式:语法格式:ENTRY注意:注意:一个程序(可包含多个源文件)中至少要有一个一个程序(可包含多个源文件)中至少要有一个ENTRY(可以有多个(可以有多个ENTRY),但一个源文件中最多只能),但一个源文件中最多只能有一个有一个ENTRY(可以没有(可以没有ENTRY)2024/4/17 周三4)ALIGNALIGN伪操作通过填充伪操作通过填充0将当前的位置以某种形式对齐。将当前的位置以某种形式对齐。语法格式:语法格式:ALIGN expr,offset其中:其中:expr:一个数字,表示对齐的单位。
26、这个数字是:一个数字,表示对齐的单位。这个数字是2的整数的整数次幂,范围在次幂,范围在20231之间。之间。如果没有指定如果没有指定expr,则当前位置对齐到下一个字边,则当前位置对齐到下一个字边界处界处。Offset:偏移量,可以为常数或数值表达式。:偏移量,可以为常数或数值表达式。不指定不指定offset表示将当前位置对齐到以表示将当前位置对齐到以expr为单位的起始位置。为单位的起始位置。2024/4/17 周三例例1:short DCB 1 ;本操作使字对齐被破坏本操作使字对齐被破坏ALIGN ;重新使其为字对齐重新使其为字对齐MOV R0,1例例2:ALIGN 8 ;当前位置以当前位
27、置以2个字的方式对齐个字的方式对齐2024/4/17 周三5)ENDEND伪操作告诉编译器已经到了源程序结尾。伪操作告诉编译器已经到了源程序结尾。语法格式:语法格式:END注意:注意:每一个汇编源程序都必须包含每一个汇编源程序都必须包含END伪操作,以伪操作,以表明本源程序的结束。表明本源程序的结束。2024/4/17 周三6)EQU EQU伪操作伪操作为数字常量、基于寄存器的值和程序中的标为数字常量、基于寄存器的值和程序中的标号定义一个字符名称号定义一个字符名称。语法格式:语法格式:name EQU expr,type其中:其中:name:为:为expr定义的字符名称。定义的字符名称。exp
28、r:基于寄存器的地址值、程序中的标号、:基于寄存器的地址值、程序中的标号、32位的地址常量或者位的地址常量或者32位的常量。位的常量。表达式,为常量。表达式,为常量。type:当:当expr为为32位常量时,可以使用位常量时,可以使用type指示指示expr的数据的类型。的数据的类型。取值为:取值为:CODE32CODE16DATA2024/4/17 周三例:例:abcd EQU 2 ;定义定义abcd符号的值为符号的值为2 abcd EQU label+16 ;定义定义abcd符号的值为符号的值为(label+16)abcd EQU 0 x1c,CODE32 ;定义定义abcd符号的值为绝对
29、地址符号的值为绝对地址 ;值值0 x1c,而且此处为,而且此处为ARM指令指令2024/4/17 周三7)EXPORT及及GLOBAL 声明一个源文件中的符号,使此符号可以被其他源文件引声明一个源文件中的符号,使此符号可以被其他源文件引用。用。语法格式:语法格式:EXPORT/GLOBAL symbol weak其中:其中:symbol:声明的符号的名称。(区分大小写):声明的符号的名称。(区分大小写)weak:声明其他同名符号优先于本符号被引用。:声明其他同名符号优先于本符号被引用。例:例:AREA example,CODE,READONLY EXPORT DoAdd DoAdd ADD R
30、0,R0,R12024/4/17 周三8)IMPORT及及EXTERN声明一个符号是在其他源文件中定义的。声明一个符号是在其他源文件中定义的。语法格式:语法格式:IMPORT symbolweakEXTERN symbolweak其中:其中:symbol:声明的符号的名称。:声明的符号的名称。2024/4/17 周三weak:当没有指定此项时,如果当没有指定此项时,如果symbol在所有的源文件在所有的源文件中都没有被定义,则连接器会报告错误。中都没有被定义,则连接器会报告错误。当指定此项时,如果当指定此项时,如果symbol在所有的源文件中都在所有的源文件中都没有被定义,则连接器不会报告错误
31、,而是进行下没有被定义,则连接器不会报告错误,而是进行下面的操作。面的操作。如果该符号被如果该符号被B或者或者BL指令引用,则该符号被设置指令引用,则该符号被设置成下一条指令的地址,该成下一条指令的地址,该B或或BL指令相当于一条指令相当于一条NOP指令。指令。其他情况下此符号被设置成其他情况下此符号被设置成0。2024/4/17 周三9)GET及及INCLUDE将一个源文件包含到当前源文件中,并将被包将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理。含的文件在其当前位置进行汇编处理。指令格式:指令格式:GET filenameINCLUDE filename其中其中:
32、filename:包含的源文件名,可以使用路径信息包含的源文件名,可以使用路径信息(可包含空格)。(可包含空格)。例:例:GET d:armfile.s2024/4/17 周三10)INCBIN将一个文件包含到当前源文件中,而被包含的文件不进将一个文件包含到当前源文件中,而被包含的文件不进行汇编处理行汇编处理指令格式:指令格式:INCBIN filename其中:其中:filename:被包含的文件名称,可使用路径信息(不能:被包含的文件名称,可使用路径信息(不能有空格)。有空格)。适用情况:适用情况:通常使用此伪操作将一个可执行文件或者任通常使用此伪操作将一个可执行文件或者任意数据包含到当前
33、文件中。意数据包含到当前文件中。例:例:INCBIN d:armfile.txt2024/4/17 周三例:编写一具有完整汇编格式的程序,实现冒泡法排序功例:编写一具有完整汇编格式的程序,实现冒泡法排序功能。设无符号字数据存放在从能。设无符号字数据存放在从0 x400004开始的区域,字数据开始的区域,字数据的数目字存放在的数目字存放在0 x400000中。中。AREA SORT,CODE,READONLYENTRYSTARTMOV R1,#0 x400000LPSUBS R1,R1,#1BEQ EXITMOV R7,R1LDR R0,=0 x400004LP1LDR R2,R0,#4LDR
34、R3,R0CMP R2,R3STRLO R3,R0,#-4STRLO R2,R0SUBS R7,R7,#1BNE LP1B LPEXITEND2024/4/17 周三4.GNU4.GNU下的伪操作和宏指令下的伪操作和宏指令 GNUGNU编译环境下的伪操作可分为以下几类:编译环境下的伪操作可分为以下几类:1 1)常量编译控制伪操作常量编译控制伪操作2 2)汇编程序代码控制伪操作汇编程序代码控制伪操作3 3)宏及条件编译控制伪操作宏及条件编译控制伪操作4 4)其他伪操作其他伪操作2024/4/17 周三1 1)常量编译控制伪操作)常量编译控制伪操作 2024/4/17 周三)汇编程序代码控制伪操作
35、)汇编程序代码控制伪操作 2024/4/17 周三)宏及条件编译控制伪操作)宏及条件编译控制伪操作2024/4/17 周三)其他伪操作)其他伪操作 2024/4/17 周三5.ADS5.ADS与与GNUGNU编译环境下的比较编译环境下的比较 2024/4/17 周三2024/4/17 周三4.4.ARM ATPCS ARM ATPCS 1.1.基本基本ATPCS ATPCS ATPCS就是就是ARM程序和程序和Thumb程序中子程程序中子程序调用的基本规则。序调用的基本规则。ATPCS规定了一些子程序规定了一些子程序间调用的基本规则。间调用的基本规则。子程序调用过程中寄存器的使用规则子程序调用
36、过程中寄存器的使用规则 数据栈的使用规则数据栈的使用规则 参数的传递规则。参数的传递规则。2024/4/17 周三相对于其他类型的相对于其他类型的ATPCSATPCS,满足基本,满足基本ATPCSATPCS的程序的执行速度更快,所占用的内存更少。的程序的执行速度更快,所占用的内存更少。它不能提供以下的支持:它不能提供以下的支持:1 1)ARMARM程序和程序和ThumbThumb程序相互调用;程序相互调用;2 2)数据以及代码的位置无关的支持;数据以及代码的位置无关的支持;3 3)子程序的可重入性;)子程序的可重入性;4 4)数据栈检查的支持。数据栈检查的支持。2024/4/17 周三1 1)
37、寄存器的使用规则)寄存器的使用规则 寄存器的使用必须满足下面的规则:寄存器的使用必须满足下面的规则:子程序间通过寄存器子程序间通过寄存器 R0R0一一R3R3来传递参数来传递参数在子程序中,使用寄存器在子程序中,使用寄存器R4R4R11R11来保存局部变量来保存局部变量 寄存器寄存器R12R12用作子程序间用作子程序间scratchscratch寄存器(用于保寄存器(用于保存存SPSP,在函数返回时使用该寄存器出栈),记作,在函数返回时使用该寄存器出栈),记作ipip。在子程序间的连接代码段中常有这种使用规。在子程序间的连接代码段中常有这种使用规则。则。2024/4/17 周三寄存器寄存器R1
38、3R13用作数据栈指针,记作用作数据栈指针,记作spsp。寄存器寄存器R14R14称为连接寄存器,记作称为连接寄存器,记作lr lr。寄存器寄存器R15R15是程序计数器,记作是程序计数器,记作pcpc。它不能用作其。它不能用作其他用途。他用途。2024/4/17 周三 ATPCS中各寄存器的使用规则及其名称中各寄存器的使用规则及其名称2024/4/17 周三2)数据栈使用规则)数据栈使用规则 栈指针通常可以指向不同的位置。当栈指针指向栈顶元栈指针通常可以指向不同的位置。当栈指针指向栈顶元素素(即最后一个入栈的数据元素即最后一个入栈的数据元素)时,称为时,称为FULL栈;当栈指栈;当栈指针指向
39、与栈顶元素针指向与栈顶元素(即最后一个入栈的数据元素即最后一个入栈的数据元素)相邻的一个相邻的一个可用数据单元时,称为可用数据单元时,称为EMPTY栈。栈。数据栈的增长方向也可以不同。当数据栈向内存地址减数据栈的增长方向也可以不同。当数据栈向内存地址减小的方向增长时,称为小的方向增长时,称为DESCENDING栈,当数据栈向内存栈,当数据栈向内存地址增加的方向增长时,称为地址增加的方向增长时,称为ASCENDING栈。栈。2024/4/17 周三 综合这两种特点可以有以下综合这两种特点可以有以下4种数据栈。种数据栈。FD Full DescendingED Empty DescendingFA
40、 Full AscendingEA Empty Ascending ATPCS规定数据栈为规定数据栈为FD类型,并且对类型,并且对数据栈的操作是数据栈的操作是8字节对齐的。字节对齐的。2024/4/17 周三3 3)数传递规则数传递规则 (1 1)参数个数可变的子程序参数传递规则:)参数个数可变的子程序参数传递规则:对于参数个数可变的子程序,当参数不超过对于参数个数可变的子程序,当参数不超过4 4个时,可个时,可以使用寄存器以使用寄存器R0R3R0R3来传递参数;当参数超过来传递参数;当参数超过4 4个时,还可个时,还可以使用数据栈来传递参数。以使用数据栈来传递参数。在参数传递时,将所有参数看
41、作是存放在连续的内存字在参数传递时,将所有参数看作是存放在连续的内存字单元中的宇数据。然后,依次将各字数据传送到寄存器单元中的宇数据。然后,依次将各字数据传送到寄存器R0R0、RlRl、R2R2、R3R3中,如果参数多于中,如果参数多于4 4个,将剩余的字数据传个,将剩余的字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈。数据先入栈。2024/4/17 周三(2 2)参数个数固定的子程序参数传递规则)参数个数固定的子程序参数传递规则 对于参数个数固定的子程序,参数传递与参数个数对于参数个数固定的子程序,参数传递与参数个数
42、可变的子程序参数传递规则不同。如果系统包含浮点运算可变的子程序参数传递规则不同。如果系统包含浮点运算的硬件部件,浮点参数将按照下面的规则传递:的硬件部件,浮点参数将按照下面的规则传递:各个浮点参数按顺序处理。各个浮点参数按顺序处理。为每个浮点参数分配为每个浮点参数分配FPFP寄存器。寄存器。分配的方法是,满足该浮点参数需要的且编号最分配的方法是,满足该浮点参数需要的且编号最小的一组连续的小的一组连续的FPFP寄存器。第一个整数参数,通过寄存器寄存器。第一个整数参数,通过寄存器R0R0R3R3来传递。其他参数通过数据栈传递。来传递。其他参数通过数据栈传递。2024/4/17 周三(3 3)子程序
43、结果返回规则)子程序结果返回规则 结果为一个结果为一个3232位的整数时,可以通过寄存器位的整数时,可以通过寄存器R0R0返回。返回。结果为一个结果为一个6464位整数时,可以通过寄存器位整数时,可以通过寄存器R0R0和和R1R1返回,依次类推。返回,依次类推。结果为一个浮点数时,可以通过浮点运算部件的结果为一个浮点数时,可以通过浮点运算部件的寄存器寄存器f0f0、d0d0或者或者s0s0来返回。来返回。结果为复合型的浮点数结果为复合型的浮点数(如复数如复数)时,可以通过寄时,可以通过寄存铅存铅f0fnf0fn或者或者d0dnd0dn来返回。来返回。对于位数更多的结果,需要通过内存来传递。对于
44、位数更多的结果,需要通过内存来传递。2024/4/17 周三2.ARM2.ARM和和ThumbThumb程序混合使用程序混合使用 在编译和汇编时,使用在编译和汇编时,使用/interwork/interwork告诉编译器生成的告诉编译器生成的目标代码遵守支持目标代码遵守支持ARMARM程序和程序和ThumbThumb程序混合使用的程序混合使用的ATPCSATPCS。它用在以下场合:。它用在以下场合:1)1)程序中存在程序中存在ARMARM程序调用程序调用ThumbThumb程序的情况。程序的情况。2)2)程序中存在程序中存在ThumbThumb程序调用程序调用ARMARM程序的情况。程序的情况
45、。3)3)需要连接器来进行需要连接器来进行ARMARM状态和状态和ThumbThumb状态切换的情状态切换的情况。况。2024/4/17 周三例如:进行状态切换的汇编程序例如:进行状态切换的汇编程序 ARMADR r0,ThumbProg+1 BX r0 ;跳到;跳到ThumbProg,程序切换到,程序切换到Thumb状志状志THUMB ;THUMB指示编译器后面的为指示编译器后面的为Thumb指令指令ThumbProg:.ADR r0,ARMProgBX r0 ;跳转到;跳转到ARMProg,程序切换到,程序切换到ARM状态状态ARM ;ARM指示编译器后面的为指示编译器后面的为ARM指令指
46、令ARMProg:MOV r4,#42024/4/17 周三4.4.ARMARM程序设计程序设计.ARM.ARM汇编语言程序设计汇编语言程序设计 ARMARM汇编语言以段(汇编语言以段(sectionsection)为单位组织源文)为单位组织源文件。件。段是相对独立的、具有特定名称的、不可分割的段是相对独立的、具有特定名称的、不可分割的指令或数据序列。指令或数据序列。段又可以分为段又可以分为代码段和数据段代码段和数据段,代码段存放执行,代码段存放执行代码,数据段存放代码运行时需要用到的数据。一代码,数据段存放代码运行时需要用到的数据。一个个ARMARM源程序至少需要一个代码段,大的程序可以源程
47、序至少需要一个代码段,大的程序可以包含多个代码段和数据段。包含多个代码段和数据段。2024/4/17 周三)ARM汇编中的文件格式汇编中的文件格式 ARM源程序文件(可简称为源文件)可以由任源程序文件(可简称为源文件)可以由任意一种文本编辑器来编写程序代码,它一般为文本意一种文本编辑器来编写程序代码,它一般为文本格式。在格式。在ARM程序设计中,常用的源文件可简单分程序设计中,常用的源文件可简单分为以下几种为以下几种.2024/4/17 周三2)ARM汇编语言语句格式汇编语言语句格式 ARM汇编语言语句格式如下所示:汇编语言语句格式如下所示:symbol instruction|directi
48、ve|pseudo-instruction;comment 其中:其中:instruction为指令。为指令。directive为伪操作。为伪操作。pseudo-instrkeuction为伪指令。为伪指令。symbol为符号。为符号。comment为语句的注释。为语句的注释。2024/4/17 周三 ARM ARM汇编语言中,符号可代表地址、变量和数字常量。汇编语言中,符号可代表地址、变量和数字常量。数字常量一般有数字常量一般有3 3种表达方式:种表达方式:十进制数十进制数,如,如7979、4 4等。等。十六进制数十六进制数,以,以0 x0 x和和&开头,如开头,如0 x3450 x345、
49、0 xFB0 xFB。n n进制数进制数,用,用n_XXXn_XXX表示,如表示,如2_011001012_01100101、8_56428_5642。标号:表示程序中的指令或数据地址的符号,代表地址。标号:表示程序中的指令或数据地址的符号,代表地址。局部标号:主要用于局部范围代码。局部标号:主要用于局部范围代码。2024/4/17 周三)ARM汇编语言程序格式汇编语言程序格式 ADS环境下环境下ARM汇编语言源程序的基本结构汇编语言源程序的基本结构:AREA EXAMPLE,CODE,READONLY ENTRY start MOV r0,#10 MOV r1,#3 ADD r0,r0,r1
50、 END 上述程序的程序体部分实现了一个简单的加法运算。上述程序的程序体部分实现了一个简单的加法运算。2024/4/17 周三GNU环境下环境下ARM汇编语言源程序的基本结构:汇编语言源程序的基本结构:.equx,45 /*定义变量定义变量x,并赋值为并赋值为45*/.equy,64 /*定义变量定义变量y,并赋值为并赋值为64*/.equstack_top,0 x1000/*定义栈顶定义栈顶0 x1000*/.global _start.text_start:/*程序代码开始标志程序代码开始标志*/MOV sp,#stack_top MOV r0,#x /*x的值放入的值放入R0 */MOV