ARM语言程序设计思路课件

上传人:风*** 文档编号:240744200 上传时间:2024-05-04 格式:PPT 页数:100 大小:611.50KB
返回 下载 相关 举报
ARM语言程序设计思路课件_第1页
第1页 / 共100页
ARM语言程序设计思路课件_第2页
第2页 / 共100页
ARM语言程序设计思路课件_第3页
第3页 / 共100页
点击查看更多>>
资源描述
第4章ARM汇编语言程序设计n4.1ARM汇编伪指令与伪操作n4.2ARM汇编语言的语句格式n4.3ARM汇编语言的程序格式n4.4ADTIDE集成开发环境n4.5ARM汇编语言程序设计举例n4.6汇编语言与C语言的混合编程1两种常用的ARM编译开发环境nADS/SDT、RealViewMDK等ARM公司推出的开发工具nGNUARM开发工具ARM汇编语言的伪操作、宏指令在不同的编译环境下有不同的编写形式和规则21)ADS/SDT、RealViewMDK等ARM公司推出的开发工具ADS由ARM公司推出,使用了CodeWarrior公司的编译器。针对ARM资源配置为用户提供了在CodeWarriorIDE集成环境下配置各种ARM开发工具的能力。以ARM为目标平台的工程创建向导,可以使用户以此为基础,快速创建ARM和Thumb工程。ARM将Keil公司收购之后,正式推出了针对ARM微控制器的开发工具RealViewMicrocontrollerDevelopmentKit(简称RealViewMDK或者MDK),它将ARM开发工具RealViewDevelopmentSuite(简称RVDS)的编译器RVCT与Keil的工程管理、调试仿真工具集成在一起,是一款非常强大的ARM微控制器开发工具。32)GNUARM开发工具GNU是“GNUsNotUnix”的递归缩写。在1983年9月27日由RichardStallman公开发起GNU计划,它的目标是创建一套完全自由的操作系统。GNU格式ARM汇编语言程序主要是面对在ARM平台上移植嵌入式Linux操作系统,GNU组织开发的基于ARM平台的编译工具有主要由GNU的汇编器as,交叉汇编器gcc和连接器ld组成。44.1ARM汇编伪指令与伪操作1.汇编语言伪指令2.ARM汇编伪操作3.GNUARM汇编伪操作51.汇编语言伪指令n伪指令是ARM处理器支持的汇编语言程序里的特殊助记符,它不在处理器运行期间由机器执行,只是在汇编时被翻译成ARM或者Thumb(或Thumb-2)指令(或指令序列),从而实现真正的指令操作。nARM伪指令包含ADR、ADRL、LDR等。61)小范围地址读取伪指令ADR格式ADRcond.Wregister,label功能将基于PC相对偏移地址或基于寄存器相对偏移地址值读取到寄存器中当地址值是字节对齐时,取值范围为255255当地址值是字对齐时,取值范围为10201020当地址值是16字节对齐时其取值范围更大ADR伪指令被汇编器编译成一条指令。汇编器通常使用ADD指令或SUB指令来实现伪操作的地址装载功能。如果不能用一条指令来实现ADR伪指令的功能,汇编器将报告错误。7示例下列指令存放在0 x8000起始的地址单元,分析汇编后的结果。.global_start.text_start:MOVR0,#0 x0FADRR0,_start.end解:汇编后的结果为:0 x00008000MOVR0,#0 x0F0 x00008004SUBR0,PC,#1282)中等范围地址读取伪指令ADRL格式ADRLcondregister,label功能将基于PC相对偏移的地址或基于寄存器相对偏移的地址值读取到寄存器中当地址值是字节对齐时,取值范围为6464KB;当地址值是字对齐时,取值范围为256256KB。当地址值是16字节对齐时,其取值范围更大。ADRL伪指令被编译器换成两条指令。即使一条指令可以完成该操作,编译器也将产生两条指令,其中一条为多余指令。如果汇编器不能在两条指令内完成操作,将报告错误,中止编译。9示例以下指令存放在0 x8000起始的地址单元,分析汇编后的结果。.global_start.text_start:MOVR0,#0 x0FADRLR0,_start.end解:汇编后的结果为:0 x00008000MOVR0,#0 x0F0 x00008004SUBR0,PC,#120 x00008008NOP(MOVR0,R0)10格式LDRcond.Wregister,=expr|label-expr功能将一个32位的常数或者一个地址值读取到寄存器中,可以看作是加载寄存器的内容。如果加载的常数符合MOV或MVN指令立即数的要求,则用MOV或MVN指令替代LDR伪指令。如果加载的常数不符合MOV或MVN指令立即数的要求,汇编器将常量放入数据缓存池,并使用一条程序相对偏移的LDR指令从数据缓存池读出常量。3)大范围地址读取伪指令LDR11示例将常数0 xff0读到R1中。LDRR3,=0 xff0;汇编后将得到:MOVR3,#0 xff0将常数0 xfff读到R1中。LDRR1,=0 xfff;汇编后将得到:LDRR1,pc,offset_to_litpoollitpoolDCD0 xfff12将place标号地址读入R1中。LDRR2,=place;汇编后将得到:LDRR2,pc,offset_to_litpoollitpoolDCDplace132.ARM汇编伪操作n伪操作(Directive)是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,对源程序运行汇编程序处理,而不是在计算机运行期间由处理器执行。n伪操作只是汇编过程中起作用,一旦汇编结束,伪操作也就随之消失。nARM公司推出的开发工具所支持的汇编伪操作符号定义伪操作数据定义伪操作汇编控制伪操作杂项伪操作141)符号定义伪操作(1)全局变量定义GCLA、GCLL及GCLS(2)局部变量定义LCLA、LCLL及LCLS格式:GCLA/GCLL/GCLS variable格式:LCLA/GCLL/GCLS variable说明variable全局/局部变量名称A算术变量(初始化为0)L逻辑变量(初始化为假F)S字符串变量(初始化为空)15(3)变量赋值伪操作SETA、SETL及SETS格式VariableSETA/SETL/SETSexpr说明Expr算术、逻辑或字符串表达式,也就是将要赋予变量的值示例LCLATest4Test3SETA0 xaaLCLLTest5Test4SETLTRUELCLSTest6Test6SETSTesting16(4)给通用寄存器列表定义名称RLIST格式:NameRLISTlist-of-registers说明Name寄存器列表的名称list-of-registers通用寄存器列表示例将寄存器列表名称定义为RegList,可在ARM指令LDM/STM中通过该名称访问寄存器列表。RegListRLISTR0-R5,R8,R10172)数据定义伪操作n数据定义伪操作一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。DCB/DCW(DCWU)/DCD(DCDU)/DCQ(DCQU)DCFD(DCFDU)/DCFS(DCFSU)LTORGSPACEMAP/FIELD18(1)DCD(DCDU)格式label DCD expr,exprlabel DCDUexpr,expr说明Label可选的程序标号;Expr表达式。DCD可能在分配的内存单元前加13字节以保证内存字对齐。当程序对内存对齐方式要求不严格时可以是DCDU伪操作。19示例StrDCBThisisatest!C_stringDCBC_string,0DataTestDCW1,2,3DataDCW-255,2*numberDCWUnumber+4DataTestDCD4,5,6DataTestDCQ10020(2)声明数据缓存池LTORG在使用LDR伪指令时,要在适当的位置加入LTROG声明数据缓存池,这样就会把要加载的数据保存到缓存池中,再使用ARM加载指令读出,如果没有使用LTROG声明数据缓冲池,则汇编器会在程序末尾自动声明。格式:LTROG21(3)分配存储空间SPACE格式labelSPACEexpr说明Label可选的程序标号;Expr分配的字节数。示例分配连续100字节的存储单元并初始化为0。DataSpaceSPACE10022(4)定义结构化内存表首地址/数据域格式MAPexpr,base_registerlabelFIELDexpr示例定义一个内存表,其首地址为0 x100。该表包含3个域:A的长度为16个字节,位置为0 x100;B的长度为32个字节,位置为0 x110;S的长度为256个字节,位置为0 x130。MAP0 x100AFIELD16BFIELD32SFIELD256一个寄存器相关的首地址定义结构化内存表。MAP0,R9;将结构化内存表的首地址设为R9的值FIELD4LABFIELD4LDRr0,LAB;相当于LDRR0,R9,#4233)汇编控制伪操作n汇编器在对程序代码进行编译时,会根据汇编控制伪操作的定义情况对程序进行编译。n常用的汇编控制伪操作条件编译(IF、ELSE、ENDIF)重复汇编(WHILE、WEND)宏定义(MACRO、MEND、MEXIT)244)杂项伪操作nAREAnALIGNnENTRYnENDnEQUnEXPORT(或GLOBAL)nEXPORTASnIMPORT/EXTERNnGET(或INCLUDE)/INCBIN25(1)段属性定义伪操作AREA格式AREAsectionname,attr,attr.说明定义一个代码段或数据段,AREA伪操作指示汇编器汇编新的代码段或数据段。一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。Sectionname指定所定义段的段名。段名若以数字开头,则该段名需用“|”括起来,如:|1_test|。Attr指定代码段或数据段的属性。在AREA伪操作中,各属性之间用逗号隔开。26段属性及说明27(2)对齐方式设置ALIGN格式:ALIGNexpr,offset,pad说明对齐方式设置ALIGN伪操作通过用零或NOP指令进行填充来使当前位置与指定的边界对齐。Expr对齐表达式。表达式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。Offset偏移量,若使用该字段,则当前位置的对齐方式为:n*expr+偏移量。Pad用作填充的字节。如果没有指定pad,用零填充28示例通过ALIGN伪操作使程序中的地址标号字对齐。AREAExample,CODE,READONLYSTARTLDRR0,=SdfjkMOVPC,LRSdfjkDCB0 x58ALIGN;声明字对齐SUBIMOVR1,R3;其他代码MOVPC,LR29(3)声明程序的入口点ENTRY格式:ENTRY说明一个完整的汇编程序中至少要有一个ENTRY,如果在程序连接时没有发现ENTRY伪操作,连接器将产生警告信息。在一个源文件里最多只能有一个ENTRY,如果多个ENTRY同时出现在源文件中,汇编时将产生错误信息。示例AREAInit,CODE,READONLYENTRY;指定应用程序的入口点30(4)源程序结尾标识END格式:END说明END伪操作用于通知汇编程序已经到了源程序的结尾。每一个汇编源文件必须以END结束。示例AREAInit,CODE,READONLYEND31(5)定义常量或标号名称EQU格式:nameEQUexpr,type说明为程序中的常量、标号等定义一个等效的符号名称。name符号名称。expr32位表达式。其值为基于寄存器的地址值、程序中的标号、32位的地址常量或32位的常量。Type数据类型,为一个可选项。示例TestEQU50;定义标号Test的值为50AddrEQU0 x55,CODE32;定义Addr的值为0 x55,且该处为32位的ARM指令32(6)声明全局标号EXPORT(或GLOBAL)格式:EXPORTsymbolWEAK,attr说明用于在程序中声明一个全局的标号,该标号可在其他的文件中引用。EXPORT可用GLOBAL代替。Symbol声明的符号名称。名称区分大小写。如果symbol被忽略,所有符号被定义为可以被其他文件引用属性。WEAK声明其他的同名标号优先于该标号被引用。attr符号属性。默认情况下,被定义为全局的(global)的符号对其他文件是“可见的”,也就是说可以被其他文件引用。33(7)将符号导出到目标文件EXPORTAS格式:EXPORTASsymbol1,symbol2说明用于修改已被编译的目标文件中的符号。Symbol1源文件中的符号名。symbol1必须在源文件中已被定义。它可以是段名、标号或常量。symbol2,希望在目标文件中出现的符号名称,该符号名称区分大小写。34(8)外部符号声明IMPORT和EXTERN格式IMPORTsymbolattrIMPORTsymbolWEAK,attrEXTERNsymbolattrEXTERNsymbolWEAK,attr说明IMPORT不管当前源文件中是否引用都导入到当前源文件的符号表中EXTERN在当前源文件中引用时才导入到当前源文件的符号表中35(9)文件包含伪操作GET和INCBIN格式GET(或INCLUDE)filenameINCBINfilename说明GET(或INCLUDE)将一个源文件包含到当前源文件中,并将被包含的文件在其当前位置进行汇编处理INCBIN将一个源文件包含到当前源文件中,但被包含文件不进行汇编处理363.GNUARM汇编伪操作n符号定义伪操作n数据定义伪操作n汇编与反汇编代码控制伪操作n预定义控制伪操作371)符号定义伪操作(1)常量定义伪操作.equ或.set格式.equ symbol,expr.set symbol,expr说明Symbol要指定的名称,它可以是以前定义过的符号;Expr表示数字常量或程序中的标号。38示例.equUndef_Mode,0 x1B.equMode_Mask,0 x1F.equNOINT,0 xC0.global_start.text_start:MRSR0,CPSR读CPSRBICR0,R0,#Mode_MaskORRR1,R0,#Undef_Mode|NOINT修改MSRCPSR_cxsf,R1进入未定义模式Stop:BStop使程序停在此处查看结果.end39(2)常量定义伪操作.equiv格式:.equivsymbol,expr说明Symbol要指定的名称,它不可以是以前定义过的符号;Expr表示数字常量或程序中的标号。40(3)声明全局变量伪操作.global或.globl格式.globalsymbol.globlsymbol说明Symbol为要声明的全局变量名称,该变量可以被其它文件引用。41(4)声明外部变量伪操作.extern格式:.extern symbol说明symbol为要声明的外部变量名称,该变量在其它文件中被定义。422)数据定义伪操作(1)字节定义.byte格式:.byteexpr,expr说明expr数字表达式或程序中的标号。(2)半字定义.hword或.short格式.hwordexpr,expr.shortexpr,expr说明expr数字表达式或程序中的标号。43(3)字定义.word或.int或.long格式.wordexpr,expr.intexpr,expr.longexpr,expr说明expr数字表达式或程序中的标号。(4)双字定义.quad格式:.quadexpr,expr说明expr数字表达式。44(6)字符串定义.ascii和.asciz或.string格式.asciiexpr,expr.ascizexpr,expr.stringexpr,expr说明expr表示字符串。(5)四字定义.octa格式:.octaexpr,expr说明expr数字表达式。45(7)单精度浮点数定义.float或.single格式.floatexpr,expr.singleexpr,expr.说明Expr为32位的IEEE单精度浮点数。(8)双精度浮点数定义.double格式:.doubleexpr,expr说明expr为64位的IEEE双精度浮点数。46(9)声明数据缓冲池.ltorg格式:.ltorg说明在使用LDR伪指令时,要在适当的位置加入.ltorg声明数据缓存池,这样就会把要加载的数据保存到缓存池中,再使用ARM加载指令读出,如果没有使用.ltorg声明数据缓冲池,则汇编器会在程序末尾自动声明。473)汇编与反汇编代码控制伪操作(1)指令集类型标识伪操作.arm.code32.thumb.code16(2)段属性定义伪操作格式:.sectionexpr说明expr为段属性,可以是.text、.data、.bss中的一个。48(3)段起始声明伪操作格式.text.data.bss49(4)对齐方式设置伪操作.align或.balign格式.alignalignment,fill.balignalignment,fill说明alignment是一个数值表达式,用于指定对齐方式,其取值在015范围内;默认为字对齐。Fill用来指定进行填充的数据。50(5)代码位置设置伪操作.org格式:.orgoffset,expr说明offset是一个数值表达式,表示地址偏移量;Expr用来指定进行填充的数据。514)预定义控制伪操作n汇编器在对程序代码进行编译时,会根据汇编控制伪操作的定义情况对程序进行编译,常用的有条件编译、宏定义和文件包含(1)文件包含伪操作.include格式:.includefile_name说明用于将一个源文件包含到当前的源文件中,所包含的文件在.include指令的位置处进行汇编处理。52(2)条件编译伪操作.if格式.iflogical_expression程序代码段A.else程序代码段B.endif(3)宏定义伪操作.macro格式.macro macronameparameter,parameter程序代码段.endm534.2ARM汇编语言的语句格式1.ARM编译环境下汇编语句格式2.ARM编译环境下汇编语句中的符号规则3.GNU环境下ARM汇编语句格式4.GNU环境下ARM汇编程序编译541.ARM编译环境下汇编语句格式n程序标号指令;注释n程序标号伪操作;注释n程序标号伪指令;注释552.ARM编译环境下汇编语句中的符号规则1)符号命名规则符号由大小写字母、数字、下划线组成,且符号是区分大小写的。符号在其作用范围内必须是唯一的。程序中的符号不要与指令助记符或者伪操作同名。局部标号可以用数字开头,其他的标号不能。562)变量数字变量逻辑变量字符串变量573)常量十进制数,如535、246。十六进制数,如0 x64、0 xff00。n_XXX,n表示n进制数,从29,XXX是具体的数字。例如:8_3777字符常量用一对单引号括起来,包括一个单字符或者标准C中的转义字符。例如A、n。字符串常量由一对双引号以及由它括住的一组字符串组成,包括标准C中的转义字符。如果需要使用双引号”或字符$,则必须用”和$代替。584)字符串表达式操作n字符串表达式一般由字符串常量、字符串变量、运算符和括号构成。n与字符串表达式相关的运算符:LEN:计算字符串长度运算符。CHR:ASCII码转换运算符。STR:字符串转换运算符。LEFT:字符串取左运算符。RIGHT:字符串取右运算符。CC:字符串连接运算符。n例如:abcSETSonedoublequoteimprobSETSliteral:CC:(abc:LEFT:4)595)地址标号n段内标号的地址在汇编时确定,而段外标号地址值在链接时确定。nPC相关标号位于目标指令前的标号或程序中的数据定义伪操作前的标号。在汇编时将被处理成PC值加上或减去一个数字常量。它常用于表示跳转指令的目标地址或代码段中所嵌入的少量数据。n寄存器相关标号在汇编时将被处理成寄存器的值加上或减去一个数字常量。它常被用于访问数据段中的数据。通常用MAP和FIELD伪操作定义,也可以用EQU伪操作定义。n绝对地址绝对地址是一个32位的数字量,使用它可以直接寻址整个内存空间。606)局部标号n局部标号是一个099之间的十进制数字,可重复定义。局部标号后面可以紧接一个通常表示该局部变量作用范围的符号。局部变量的作用范围为当前段,也可以用伪操作ROUT来定义局部标号的作用范围。n局部变量命名语法:nroutnamen局部变量引用的语法格式:%F|BA|Tnroutname汇编器默认搜索:先向后搜索,再向前搜索。从当前层次到宏最高层次,比当前层次低的层次不再搜索。61n是局部标号的数字号。routname是当前局部范围的名称。%表示引用操作。F指示汇编器只向前搜索。B指示汇编器只向后搜索。A指示汇编器搜索宏的所有嵌套层次。T指示汇编器搜索宏的当前层次。623.GNU环境下ARM汇编语句格式n程序标号:指令注释n程序标号:伪操作注释n程序标号:伪指令注释634.GNU环境下ARM汇编程序编译1)预处理nGNU汇编器as的内部预处理包括:移除多余的间隔符及代码中的所有注释,并将字符常量转换为数字值。它不作宏处理和文件包含处理,但这些事情可以交由gcc编译器去做,文件包含可以用.include伪指令来实现。642)注释nGNUARMAssembly可识别的注释方式有:C风格多行注释符/*.*/或GNU单行注释符“”或“#”。3)符号n与C语言基本一致,符号名由字母、数字以及_和.组成,大小写敏感。654)段与重定位n链接器ld用于把多个目标文件合并为一个可执行文件。汇编器as生成的目标文件都假定从地址0开始,ld为其指定最终的地址。链接器ld把目标文件中的每个section都作为一个整体,为其分配运行的地址。6667n在ARM(Thumb)汇编语言程序中以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段(CodeSection)和数据段(DataSection),代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映像文件。n可执行映像文件通常由以下几部分构成。一个或多个代码段,代码段的属性为只读。零个或多个数据段,数据段的属性为可读写。数据段可是被初始化的数据段或没有被初始化的数据段(ZI,zeroinitialized)。4.3汇编语言的程序格式681.在ARM集成开发环境下AREAFCTRL,CODE,READONLY;声明代码FCTRLENTRY;标识程序入口STARTMOV R0,#0X3000;初始化寄存器MOV R1,#0X10000001MOVR2,#100loop_1STR R1,R0,#4ADDR1,R1,#1SUBSR2,R2,#1BNE loop_169MOV R0,#0X3000MOV R2,#100MOV R9,#0MOV R8,#0loop_2LDR R1,R0,#4ADDSR8,R1,R8ADC R9,R9,#0SUBSR2,R2,#1BNE loop_2StopBStopEND;文件结束702.在GNUARM开发环境下.global_start.text_start:MOV R0,#0X3000初始化寄存器MOV R1,#0X10000001MOV R2,#100loop_1:STRR1,R0,#4ADD R1,R1,#1SUBS R2,R2,#1BNEloop_171MOV R0,#0X3000MOV R2,#100MOV R9,#0MOV R8,#0loop_2:LDR R1,R0,#4ADDSR8,R1,R8ADCR9,R9,#0SUBSR2,R2,#1BNEloop_2Stop:BStop.end文件结束724.4ADTIDT集成开发环境nADT嵌入式开发环境由ADTEmulatorforARM和ADTIDEforARM组成。nADTEmulatorforARM通过JTAG实现主机和目标机之间的调试支持功能。目标程序直接在目标板上运行,通过ARM芯片的JTAG边界扫描口进行调试。nADTIDEforARM为用户提供高效明晰的图形化嵌入式应用软件开发环境,包括一整套完备的面向嵌入式系统的开发和调试工具:源码编辑器、工程管理器、工程编译器(编译器、汇编器和连接器)、集成调试环境、ADTEmulatorforARM调试接口等。73744.5ARM汇编语言程序设计举例例1:内存数据的拷贝。.global_start.text.equnum,20_start:ldrr0,=srcldrr1,=dstmovr2,#nummovsp,#0 x0c700000blockcopy:movsr3,r2,lsr#3beqcopywordsstmfdsp!,r4-r1175octcopy:ldmiar0!,r4-r11stmiar1!,r4-r11subsr3,r3,#1bneoctcopyldmfdsp!,r4-r11copywords:andsr2,r2,#7beqstop76workcopy:ldrr3,r0,#4strr3,r1,#4subsr2,r2,#1bneworkcopystop:bstop.ltorgsrc:.long1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4dst:.long0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.end77例2:内存数据格式大小端转换操作.global_start.equNUM,20操作字内存单元个数.text_start:MOVR2,#NUMLDRR0,=0 x9000内存起始地址LDRR4,=0 x44332201Init_mem:STRR4,R0,#4SUBSR2,R2,#1ADDR4,R4,#1BNEInit_mem78MOVR2,#NUMLDRR0,=0 x9000Conversion:LDRR1,R0EORR3,R1,R1,ROR#16BICR3,R3,#0 x0FF0000MOVR1,R1,ROR#8EORR1,R1,R3,LSR#8STRR1,R0,#4SUBSR2,R2,#1BNEConversionStop:BStop.end文件结束79例3:选择排序.global_start.text_start:LDR R0,=Datas输入数据首地址LDR R1,=Num数据个数LDR R1,R1Sel_Sort:MOV R1,R1,LSL#2将数据个数转化为数据尾地址SUB R1,R1,#4ADD R1,R0,R1SUB R0,R0,#480Sort_L1:LDR R4,R0,#4!TEQ R1,R0检查是否排序结束BEQ Sort_FinishMOV R2,R0MOVR3,R0Sort_L2:LDR R5,R2,#4!取出指针所指的数据CMP R4,R5BLT Sort_L3MOVR3,R2更新当前最小数据MOVR4,R5Sort_L3:TEQ R1,R2BNESort_L281Sort_L4:TEQ R0,R3BEQ Sort_L1SWP R4,R4,R0STR R4,R3BSort_L1Sort_Finish:Stop:BStop.dataDatas:.int0 xAABBCC11,0 xAABBCC66,0 xAABBCC77.int0 xAABBCC33,0 xAABBCC55,0 xAABBCC44,Num:.int6.end82例4:实现字符串的逆序拷贝.global_start.text_start:LDR R0,=SrcString源字符串指针LDR R1,=DstString目标字符串指针StrCopyDes:MOV R4,#0字符串长度记录寄存器Strcpydes_L1:计算字符串的长度LDRBR2,R0,#1ADD R4,R4,#1TST R2,#0 xFFBNE Strcpydes_L183SUB R4,R4,#1SUB R0,R0,#2R0指向源字符串的末尾MOV R3,R1R3作为目标串的游标指针Strcpydes_L2:LDRBR2,R0,#-1逐个拷贝字符串STRBR2,R3,#1SUBSR4,R4,#1BNE Strcpydes_L284Strcpydes_L3:STRBR4,R3#向目标串末尾写0,此处R4的值一定为0Stop:BStop.dataSrcString:.stringHelloWorld!DstString:.string.end854.6汇编语言与C语言的混合编程n在嵌入式程序设计中,有些场合(如对具体的硬件资源进行访问)必须用汇编语言来实现。1.过程调用标准AAPCS2.在嵌入式C语言程序中嵌入汇编语言3.ARM汇编语言与嵌入式C程序相互调用861.过程调用标准AAPCS为了使不同编译器编译的程序之间能够相互调用,必须为子程序间的调用规定一定的规则。AAPCS(ProcedureCallStandardfortheARMArchitecture),即ARM体系结构过程调用标准。它是ABI(ApplicationBinaryInterface(ABI)fortheARMArchitecture(basestandard)BSABI)标准的一部分。可以使用“-apcs”选项告诉编译器将源代码编译成符合AAPCS调用标准的目标代码。871)寄存器使用规则子程序间通过寄存器R0R3传递参数,寄存器R0R3可记作A1A4。当参数个数超过4个时,超过部分使用数据栈进行参数传递。被调用的子程序在返回前无须恢复寄存器R0R3的内容。在子程序中,ARM状态下使用寄存器R4R11来保存局部变量,寄存器R4R11可记作V1V8;Thumb状态下只能使用R4R7来保存局部变量。寄存器R12用作子程序间调用时临时保存栈指针,函数返回时使用该寄存器进行出栈,记作IP;在子程序间的链接代码中常有这种使用规则。882)数据栈使用规则通用寄存器R13用作数据栈指针,记作SP。通用寄存器R14用作链接寄存器;通用寄存器R15用作程序计数器,记作PC。过程调用标准规定数据栈为FD类型,并且对数据栈的操作时要求8字节对齐的。893)ARM寄存器在函数调用过程中的保护规则902.在嵌入式C语言程序中嵌入汇编语言GNUARM环境下的格式91示例void my_strcpy(constchar*src,char*dst);int_main()constchar*a=Helloworld!;charb20;my_strcpy(a,b);voidmy_strcpy(constchar*src,char*dst)_asm(lop1:ldrbr4,r0,#0 x1strbr4,r1,#0 x1cmpr4,#0 x0bnelop1);923.ARM汇编语言与嵌入式C程序相互调用1)汇编程序调用C程序在GNUARM编译环境下,汇编程序中要使用.extern伪操作声明将要调用的C程序。示例设计程序,用ARM汇编语言调用C语言实现20!的阶乘操作,并将64位结果保存到寄存器R0、R1中,其中R1中存放高32位结果。93建立汇编源文件start.s/*start.s*/.global_start.globalFactorial.EQUNi,20.text_start:MOVr0,#NiBLFactorialstop:Bstop.end94建立C语言源文件factorial.c/*factorial*/longlongFactorial(charN)chari;longlongNx=1;for(i=1;i=N;i+)Nx=Nx*i;returnNx;952)C程序调用汇编程序n在GNUARM编译环境下,在汇编程序中要使用.global伪操作声明汇编程序为全局的函数,可被外部函数调用,同时在C程序中要用关键字extern声明要调用的汇编语言程序。n示例设计程序,用C语言调用ARM汇编语言实现20的阶乘(20!)操作,并将64位结果保存到0 xFFFFFFF0开始的内存地址单元,按照小端格式低位数据存放在低地址单元。96建立启动C程序的代码/*start4.s*/.global_start.text_start:BMain.end97建立C语言源文件main.cexternvoidFactorial(charNx);Main()charN=20;Factorial(N);while(1);98建立汇编源文件Factorial.s.globalFactorialFactorial:movr8,r0movr9,#0subr0,r8,#1loop:movr1,r9umullr8,r9,r0,r8mlar9,r1,r0,r9subsr0,r0,#1bneloopldrr0,=0 xfffffff0stmiar0,r8,r9movpc,lr99小结ARM汇编伪指令:ADR、ADRL、LDRARM汇编伪操作、GNUARM汇编伪操作ARM汇编语言的语句格式和程序格式ADTIDE集成开发环境ARM汇编语言程序设计举例汇编语言与C语言的混合编程100
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 办公文档 > 教学培训


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!