




已阅读5页,还剩61页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于ARM的程序设计,西安交通大学软件学院杜小智xzdu,基于ARM的程序设计,ARM汇编语言的伪操作、宏指令与伪指令ARM汇编语言程序设计C与汇编语言混合编程基于ADS环境的软件开发实例,两种常见的ARM编译开发环境,ADS/SDTIDE开发环境由ARM公司开发,使用了CodeWarrior公司的编译器;ARM公司最新的开发环境是RealViewMDK。集成了GNU开发工具的IDE开发环境由GNU的汇编器as、交叉编译器gcc和链接器ld等组成。,ADS编译环境下的伪操作和宏指令,ADS编译环境下的伪操作可分为以下几类:1、符号定义(SymbolDefinition)伪操作2、数据定义(DataDefinition)伪操作3、汇编控制(AssemblyControl)伪操作4、信息报告(Reporting)伪操作5、其他(Miscellaneous)伪操作,符号定义类伪指令,符号定义伪操作用于定义ARM汇编程序中的变量,对变量进行赋值以及定义寄存器名称。包括以下伪操作。GBLA,GBLL,GBLS声明全局变量LCLS.LCLL,LCLD声明局部变量SETA,SETL,SETS给变量赋值。RLIST为通用寄存器列表定义名称。CN为协处理器的寄存器定义名称。CP为协处理器定义名称。DN和SN为VFP的寄存器定义名称。FN为FPA的浮点寄存器定义名称。,一、符号定义伪操作,示例:GBLLPLL_ON_STARTPLL_ON_STARTTRUEGBLAENTRY_BUS_WIDTHENTRY_BUS_WIDTHSETA16,;定义全局逻辑变量PLL_ON_START;给全局逻辑变量PLL_ON_START赋值;定义全局数字变量ENTRY_BUS_WIDTH;给全局数字变量ENTRY_BUS_WIDTH赋值,二、数据定义伪操作,1.SPACE分配一片连续的存储区域并初始化为0。其中,表达式表示要分配的字节数。DataSpaceSPACE100;分配连续100字节的存储单元并初始化为0。2.MAP和FIELDMAP伪指令用于定义一个结构化的内存表的首地址。MAP也可用“”代替。FIELD伪指令用于定义一个结构化的内存表的数据域。FIELD也可用“#”代替。MAP0X1000;定义结构化内存表首地址的值为0X1000FirFIELD16;定义Fir的长度为16字节,位置为0X1008SecFIELD32;定义Sec的长度为32字节,位置为0X1010ThrFIELD256;定义Thr的长度为256字节,位置为0X10303.存储单元分配DCBDCDDCW,三、汇编控制伪操作,四、信息报告伪操作,五、其他伪操作,1.AREA:用于定义一个代码段或数据段。AREAInit,CODE,READONLYAREARamData,DATA,READWRITE2.ALIGN可通过添加字节的方式,使当前位置满足一定的对齐方式。3.引用指令EXPORTGLOBALIMPORTEXTERN4.包含指令GETINCLUDEINCBIN,GEToption.sGETmemcfg.sGET2410addr.s.AREAInit,CODE,READONLYENTRYBResetHandle.ResetHandleldrr0,=WTCON;禁止看门狗ldrr1,=0 x0strr1,r0ldrr0,=INTMASK;禁止所有中断ldrr1,=0 xffffffffstrr1,r0,ldrr0,=INTSUBMSK;禁止所有子中断ldrr1,=0 x7ffstrr1,r0ALIGNAREARamData,DATA,READWRITE_ISR_STARADDRESSHandleReset#4END,首先用GET伪指令将3个源文件包含到当前的源文件中,被包含的源文件在当前位置进行汇编处理。,ARM伪指令,ARM伪指令不属于ARM指令集中的指令,是为了编程方便而定义的。伪指令可以像其它ARM指令一样使用,但在编译时这些指令将被等效的ARM指令代替。ARM伪指令有四条,分别为ADR伪指令、ADRL伪指令、LDR伪指令、NOP伪指令。,ARM指令集,小范围的地址读取,ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。,ADRcondregister,expr,ADR伪指令格式,指令执行的条件码,加载的目标寄存器,地址表达式,地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-255255;当地址值是字对齐时,其取指范围为-10201020;当地址值是16字节对齐时,其取指范围将更大。,ARM指令集,.ADRR0,Delay.DelayMOVR0,r14.,使用伪指令将程序标号Delay的地址存入R0,应用示例(源程序):,.0 x20ADDr0,pc,#0 x3c.0 x64MOVr0,r14.,编译后的反汇编代码:,地址,程序代码,ARM指令集,中等范围的地址读取,ADRLcondregister,expr,ADRL伪指令格式,指令执行的条件码,加载的目标寄存器,地址表达式,地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-64K64K;当地址值是字对齐时,其取指范围为-256K256K;当地址值是16字节对齐时,其取指范围将更大。,ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。,ARM指令集,.startMOVR0,#10ADRLR4,start+60000.,使用伪指令将程序标号Delay的地址存入R0,应用示例(源程序):,0 x1cMOVR0,#100 x20ADDr4,pc,#0 xe8000 x24ADDr4,r4,#0 x254.,编译后的反汇编代码:,地址,程序代码,ARM指令集,大范围的地址读取,LDRcondregister,=expr,LDR伪指令格式,指令执行的条件码,加载的目标寄存器,基于PC的地址表达式或外部表达式,地址表达式expr的取指范围:当地址值不是字对齐时,其取指范围为-64K64K;当地址值是字对齐时,其取指范围为-256K256K;当地址值是16字节对齐时,其取指范围将更大。,LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。,ARM指令集,.LDRR1,=InitStack.InitStackMOVR0,LR.,使用伪指令将程序标号Delay的地址存入R1,应用示例(源程序):,.0 x20LDRR1,0 xb4.0 x64MOVR0,LR.0 xb4DCD0 x64,编译后的反汇编代码:,ARM指令集,大范围的地址读取,LDR伪指令被汇编成一条LDR指令,并在文字池中定义了一个常量,该常量为InitStack标号的地址注意:1.从指令位置到文字池的偏移量必须小于4KB;2.与ARM指令的LDR相比,伪指令的LDR的参数有“=”号。,ARM指令集,空操作伪指令,NOP伪指令在汇编时将会被代替成ARM中的空操作,比如可能是“MOVR0,R0”指令等。NOP可用于延时操作。,NOP,NOP伪指令格式,应用示例(延时子程序):,DelayNOP;空操作NOPNOPSUBSR1,R1,#1;循环次数减一BNEDelay;如果循环没有结束,跳转Delay继续MOVPC,LR;子程序返回,基于ARM的程序设计,ARM汇编语言的伪操作、宏指令与伪指令ARM汇编语言程序设计C与汇编语言混合编程基于ADS环境的软件开发实例,ARM汇编中的文件格式,ARM源程序文件(可简称为源文件)可以由任意一种文本编辑器来编写程序代码,它一般为文本格式。在ARM程序设计中,常用的源文件可简单分为以下几种:,ARM汇编语言语句格式,ARM汇编语言语句格式如下所示:symbolinstruction|directive|pseudo-instruction;comment其中:symbol为符号。instruction为指令。directive为伪操作。pseudo-instruction为伪指令。comment为语句的注释。,ARM汇编语言程序格式:,ARM汇编语言是以段(section)为单位来组织源文件的。段是相对独立的、具有特定名称的、不可分割的指令或者数据序列。段又可以分为代码段和数据段,代码段存放执行代码,数据段存放代码运行时需要用到的数据。一个ARM源程序至少需要一个代码段,大的程序可以包含多个代码段和数据段。,ARM汇编语言语句格式,举例说明ARM汇编语言源程序的基本结构:,AREAEXAMPLE,CODE,READONLYENTRYstartMOVr0,#10MOVr1,#3ADDr0,r0,r1END本程序的程序体部分实现了一个简单的加法运算。,ARM汇编语言语句格式,汇编语言子程序调用及返回,1、子程序的调用在ARM汇编语言中,子程序调用是通过BL指令来完成的。BL指令的语法格式如下:BLsubname其中,subname是被调用的子程序的名称。2、子程序的返回在返回调用子程序时,转移链接指令保存到LR寄存器(R14)中的值需要拷贝回程序寄存器PC(R15)。,汇编语言子程序调用及返回,子程序返回的方法1、对于最简单的子程序,一条MOV指令就可以完成子程序的返回。SUB2MOVPC,R14;把R14拷贝到R15来返回2、对于在子程序中出现嵌套调用时,链接寄存器LR中的返回地址可能会在第二次调用时被覆盖,所以需要将返回地址压入堆栈来进行保存。SUB1STMFDR13!,R0-R2,R14;保存工作寄存器和链接BLSUB2LDMFDR13!,R0-R2,PC;恢复工作寄存器和链接,ARM汇编程序实例,简单的ARM指令程序AREAARMex,COED,READONLY;设置本段程序的名称及属性、;代码段的名称为ARMexENTRY;标记要执行的第一条指令startMOVR0,#10;设置参数MOVR1,#3ADDR0,R0,R1;R0=R0+R1stopMOVR0,#文件的结束标尺,嵌入式C语言程序设计技巧,变量定义参数传递循环条件,变量定义,一、在变量声明的时候,最好把所有相同类型的变量放在一起定义,这样可以优化存储器布局。例子:chara;chara;shortb;charc;charc;shortb;intd;intd;在数据区里的布局:,变量定义,二、对于局部变量类型的定义,使用short或char来定义变量并不是总能节省存储空间。有时使用32位int或unsingedint局部变量更有效率一些。不同类型局部变量的编译结果:,intwordinc(inta)returna+1;,shortshortinc(shorta)returna+1;,charcharinc(chara)returna+1;,变量定义,三、变量定义中,为了精简程序,程序员总是竭力避免使用冗余变量。但有时使用冗余变量可以减少存储器访问的次数这可以提高系统性能。,参数传递,为了使单独编译的C语言程序和汇编程序能够互相调用,定义了统一的函数过程调用标准ATPCS。ATPCS定义了寄存器组中的R0R3作为参数传递和结果返回寄存器,如果参数数目超过四个,则使用堆栈进行传递。内部寄存器的访问速度是远远大于存储器的,所以要尽量使参数传递在寄存器里面进行,即应尽量把函数的参数控制在四个以下。,循环条件,计数循环是程序中十分常用的流程控制结构,一般有以下两种形式:for(loop=1;loop=limit;loop+)for(loop=limit;loop!=0;loop-)这两种循环形式在逻辑上并没有效率差异,但是映射到具体的体系结构中时,就产生了很大的不同,如下图所示。,循环条件,intfact1(intlimit)for(i=1;i=limit;i+)fact=fact*i;,intfact2(intlimit)for(i=limit;i!=0;i-)fact=fact*i;,fact10 x000010:MULR2,R1,R20 x000014:ADDR1,R1,#10 x000018:CMPR1,R00 x00001c:BLE0 x0000100 x000024:MOVPC,LR,fact20 x000010:MULR0,R1,R00 x000014:SUBSR1,R1,#10 x000018:BLE0 x000010,基于ARM的程序设计,ARM汇编语言的伪操作、宏指令与伪指令ARM汇编语言程序设计C与汇编语言混合编程基于ADS环境的软件开发实例,C与汇编语言混合编程,ATPCS介绍内嵌汇编C和ARM汇编程序间相互调用,ATPCS介绍,ATPCS是ARM程序和Thumb程序中子程序调用的基本规则,目的是为了使单独编译的C语言程序和汇编程序之间能够相互调用。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。,一、寄存器的使用规则,1.子程序间通过寄存器R0-R3来传递参数,此时寄存器R0-R3可以记作A1-A4,被调用的子程序在返回前无需恢复寄存器R0-R3的内容。2.子程序中,使用寄存器R4-R11来保存局部变量,这时寄存器可以记作V1-V8。若子程序中用到了寄存器V1-V8中的某些,子程序进入时必须保存这些用到的寄存器,在返回时必须恢复。3.寄存器R12用作子程序间临时寄存器,记作IP,4.寄存器P13用作堆栈指针,记作SP。在子程序中,R13不能用作其他用途,进入和退出子程序时的值必须相等。5.寄存器R14用作链接寄存器,LR,一般用于保存子程序的返回地址。6.寄存器R15是程序寄存器,PC,它不能用作其他用途。,一、寄存器的使用规则,根据堆栈指针指向位置的不同和增长方向的不同可以分为以下4种数据栈:1、FD(FullDescending)满递减2、ED(EmptyDescending)空递减3、FA(FullAscending)满递增4、EA(EmptyAscending)空递增ATPCS规定数据栈为FD(满递减)类型,并且对数据栈的操作是8字节对齐的。,二、数据栈的使用规则,1、参数个数固定的子程序参数传递规则第一个整数参数,通过寄存器R0R3来传递。其他参数通过数据栈传递。2、参数个数可变的子程序参数传递规则当参数不超过4个时,可以使用寄存器R0R3来传递参数;当参数超过4个时,还可以使用数据栈来传递参数。3、子程序结果返回规则结果为一个32位的整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和R1返回,依次类推。,三、参数的使用规则,内嵌汇编,在C程序中嵌入汇编程序可以实现一些高级语言没有的功能,并可以提高执行效率。armcc和armcpp内嵌汇编器支持完整的ARM指令集;tcc和tcpp用于Thumb指集。内嵌的汇编指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的变量定义,数据交换必须通过ATPCS进行。嵌入式汇编在形式上表现为独立定义的函数体。,一、在C中内嵌汇编指令的语法格式,_asm(“指令;指令”):ARMC汇编器使用关键字“_asm。如果有多条汇编指令需要嵌入,可以用“”将它们归为一条语句。如:_asm指令;指令指令需要特别注意的是_asm是两个下划线。,(1)使能中断程序,_inlinevoidenable_IRQ(void)inttmp;;定义整形临时变量_asm;内嵌汇编语言程序MRStmpCPSRBICtmp,tmp,#0 x80MSRCPSR_ctmp,1、操作数可以是寄存器、常量或C表达式。它们可以是char、short或者int类型,而且是作为无符号数进行操作。2、内嵌的汇编指令中使用物理寄存器有一些限制。3、常量前的符号“#”可以省略4、只有指令B可以使用C程序中的标号,指令BL不能使用C程序中的标号。5、不支持汇编语言中用于内存分配的伪操作。6、指令中如果包含常量操作数,该指令可能会被汇编器展开成几条指令。,二、内嵌的汇编指令的特点,1、内嵌汇编器不支持通过“”指示符或PC获取当前指令地址;2、不支持LDRRn,=expression伪指令,而使用MOVRn,expression指令向寄存器赋值;3、不支持标号表达式;4、不支持ADR和ADRL伪指令;5、不支持BX和BLX指令;6、不可以向PC赋值;7、使用0 x前缀替代“”表示十六进制数。,三、内嵌汇编器与armasm汇编器的区别,1、必须小心使用物理寄存器,如:R0R3,LR和PC。2、不要使用寄存器寻址变量。3、使用内嵌汇编时,编译器自己会保存和恢复它可能用到的寄存器,用户无须保存和恢复寄存器。4、LDM和STM指令的寄存器列表只允许物理寄存器。5、汇编语言用“,”作为操作数分隔符。,四、内嵌汇编注意事项,C和ARM汇编程序间相互调用,在C和ARM汇编程序之间相互调用必须遵守ATPCS规则。C和汇编之间的相互调用可以从以下这三方面来介绍:,1、汇编程序对C全局变量的访问2、在C语言程序中调用汇编程序3、在汇编程序中调用C语言程序,一、汇编语言中使用C语言定义的全局变量,汇编程序可以通过地址间接访问在C语言程序中声明的全局变量。通过使用IMPORT关键词声明全局变量,再将该变量地址装载到寄存器中。(利用LDR和STR指令根据全局变量的地址可以访问它们。)对于不同类型的变量,需要采用不同选项的LDR和STR指令,如下所示:,unsignedcharLDRB/STRBunsignedshortLDRH/STRHunsignedintLDR/STRcharLDRSB/STRSBshortLDRSH/STRSH,AREAglobals,CODE,READONLYEXPORTasmsub;声明该符号的代码段可被其它程序引用IMPORTglobv1;声明一个来自外部的变量。asmsub;asmsub代码段LDRr1,=globv1;将声明变量的内存地址读到r1中。LDRr0,r1;将其值读到r0中。ADDr0,r0,#2;STRr0,r1;将处理后的值返回。MOVpc,lrEND上例程序中的globv1是一个C程序中声明的全局变量。在汇编程序中要用IMPORT声明该变量,用将内存地址读取到R1中。修改后将寄存器的值赋给变量Globv1。,一、汇编语言中使用C语言定义的全局变量示例,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守ATPCS。C中调用汇编文件的函数主要工作有两个:1.在汇编程序中需要使用EXPORT伪操作来导出函数名,并用该函数名作为汇编代码段的标识,最后用movpc,lr返回;2.在C程序调用该汇编程序之前需要在C语言程序中声明函数原型,并用extern关键词来声明该汇编程序。,二、在C语言程序中调用汇编程序,#includeexternvoidstrcopy(char*d,constchar*s);intmain()constchar*srcstr=Firststring-source;chardststr=Secondstring-destination;/*dststrisanarraysinceweregoingtochangeit*/printf(Beforecopying:n);printf(%sn%sn,srcstr,dststr);strcopy(dststr,srcstr);printf(Aftercopying:n);printf(%sn%sn,srcstr,dststr);return0;,二、在C语言程序中调用汇编程序,;scopyAREASCopy,CODE,READONLYEXPORTstrcopystrcopy;r0pointstodestinationstring;r1pointstosourcestringLDRBr2,r1,#1;loadbyteandupdateaddressSTRBr2,r0,#1;storebyteandupdateaddress;CMPr2,#0;checkforzeroterminatorBNEstrcopy;keepgoingifnotMOVpc,lr;ReturnEND,为了保证程序调用时参数的正确传递,汇编程序的设计要遵守ATPCS。在C程序中不需要使用任何关键字来声明将被汇编语言调用的C程序,但是在汇编程序调用该C程序之前需要在汇编语言程序中使用IMPORT伪操作来声明该C程序。在汇编程序中通过BL指令来调用子程序。,三、在汇编程序中调用C语言的函数,intg(inta,intb,intc,intd,inte)returna+b+c+d+e;intf(inti)(returng(i,2*i,3*i,4*i,5*i);EXPORTfAREAasmf,CODE,READONLYIMPORTg;iisinr0STRlr,sp,#-4!;preservelrADDr1,r0,r0;compute2*i(2ndparam)ADDr2,r1,r0;compute3*i(3ndparam)ADDr3,r1,r2;compute5*iSTRr3,sp,#-4!
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 个人协议用工范文
- 脑梗塞康复护理健康教育
- 2025年事业单位工勤技能-湖南-湖南地质勘查员三级(高级工)历年参考题库典型考点含答案解析
- 2025年事业单位工勤技能-湖北-湖北行政岗位工四级(中级工)历年参考题库含答案解析
- 2025年事业单位工勤技能-湖北-湖北检验员四级(中级工)历年参考题库典型考点含答案解析
- 2025年医药电商平台医药电商保险与合规监管报告
- 2025年事业单位工勤技能-湖北-湖北护理员五级(初级工)历年参考题库含答案解析
- 2025年事业单位工勤技能-湖北-湖北地图绘制员五级(初级工)历年参考题库典型考点含答案解析
- 2025-2030中国素颜霜市场需求状况及销售模式预测分析报告
- 2025年事业单位工勤技能-浙江-浙江药剂员一级(高级技师)历年参考题库含答案解析(5套)
- 技术团队分红协议书
- 应聘个人简历标准版范文
- 2025年中国智慧养殖行业市场占有率及投资前景预测分析报告
- 全面深化信息安全培训提高医护人员的保护意识与能力水平
- 2025-2030中国工业CT行业市场运行分析及发展趋势与投资研究报告
- 废气处理合同协议
- 肿瘤科实习生护理小讲课
- 劳动教育校本课程研究(8篇)
- 2025-2030中国余热回收行业市场现状供需分析及投资评估规划分析研究报告
- 2025小红书商业影像婚美行业峰会
- GB/T 45304-2025干欧芹
评论
0/150
提交评论