欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    嵌入式系统原理及应用教程第4章.ppt

    • 资源ID:6437478       资源大小:501.50KB        全文页数:131页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    嵌入式系统原理及应用教程第4章.ppt

    主讲内容,第1章 嵌入式系统概述第2章 ARM微处理器概述与编程模型第3章 ARM9指令系统第4章 嵌入式程序设计基础第5章 嵌入式内部可编程模块第6章 嵌入式接口技术应用第7章 软件开发环境,第4章 嵌入式程序设计基础,基于ARM的编译器一般都支持汇编语言的程序设计、C/C+语言的程序设计及两者的混合编程。本章介绍ARM的嵌入式程序的基础知识伪指令汇编语言的语句格式汇编语言C/C+语言的混合编程.,4.1 伪指令,在ARM汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊指令助记符为伪指令,他们所完成的操作称为伪操作。伪指令在源程序中的作用是既要把正常的程序用指令表达给计算机以外,又要把程序设计者的意图表达给编译器.例如:要告诉编译器程序段的开始和结束,需要定义数据等.,在ARM的汇编程序中,我们把伪指令分为三部分介绍:通用伪指令 与ARM指令相关的伪指令与Thumb指令相关的伪指令,4.1 伪指令,4.1.1 通用伪指令,通用伪指令包括:符号定义伪指令数据定义伪指令汇编控制伪指令及其他一些常用伪指令等。,4.1.1 通用伪指令,1.符号定义伪指令 符号定义伪指令用于声明ARM汇编程序中的变量、对变量赋值以及定义寄存器的名称等操作。常见的符号定义伪指令有如下几种:(1)GBLA、GBLL和GBLS语法格式:GBLA(GBLL或GBLS)全局变量名 GBLA、GBLL和GBLS伪指令是声明全局变量的伪指令,用于定义一个ARM程序中的全局变量,并将其初始化。,4.1.1 通用伪指令,其中:GBLA用于声明一个全局的数字变量,并初始化为0;GBLL伪指令用于声明一个全局的逻辑变量,并初始化为F(假);GBLS伪指令用于声明一个全局的字符串变量,并初始化为空;对于全局变量来说,变量名在源程序中必须是唯一的。,1.符号定义伪指令 符号定义伪指令用于声明ARM汇编程序中的变量、对变量赋值以及定义寄存器的名称等操作。常见的符号定义伪指令有如下几种:(1)GBLA、GBLL和GBLS,4.1.1 通用伪指令,指令示例:GBLADATE1;声明一个全局数字变量DATE1GBLLDATE1;声明一个全局逻辑变量DATE2GBLSDATA3;声明一个全局的字符串变量DATE3DATE3SETS“Testing”;将该变量赋值为“Testing”,4.1.1 通用伪指令,(2)LCLA、LCLL和LCLS语法格式:LCLA(LCLL或LCLS)局部变量名 LCLA、LCLL和LCLS伪指令是声明局部变量伪指令,用于定义一个ARM程序中的局部变量,并将其初始化。其中:LCLA用于声明一个局部的数字变量,并初始化为0;LCLL用于声明一个局部的逻辑变量,并初始化为F(假);LCLS用于声明一个局部的字符串变量,并初始化为空。对于局部变量来说,变量名在使用的范围内必须是唯一的,范围限制在定义这个变量的宏指令程序段内。,4.1.1 通用伪指令,指令示例:LCLADATE4;声明一个局部数字变量DATE4LCLLDATE5;声明一个局部的逻辑变量DATE5DATA4SETL 0 x10;为变量DATE4赋值为0 x10LCLSDATA6;声明一个局部的字符串变量DATA6,4.1.1 通用伪指令,(3)SETA、SETL和SETS语法格式:变量名 SETA(SETL或SETS)表达式 SETA、SETL、SETS是变量赋值伪指令,用于给一个已经定义的全局变量或局部变量赋值。其中:SETA用于给一个数学变量赋值;SETL用于给一个逻辑变量赋值;SETS用于给一个字符串变量赋值;,4.1.1 通用伪指令,指令示例:GBLA EXAMP1;先声明一个全局数字变量EXAMP1 EXAMP1 SETA0 xaa;将变量EXAMP1赋值为0 xaaLCLL EXAMP2;声明一个局部的逻辑变量EXAMP2EXAMP1 SETLTRUE;将变量EXAMP1赋值为TRUEGBLA EXAMP3;先声明一个全局字符串变量EXAMP3 EXAMP3 SETS“string”;将变量EXAMP3赋值为string,4.1.1 通用伪指令,(4)RLIST语法格式:名称 RLIST 寄存器列表 RLIST伪指令是定义通用寄存列表伪指令,通用寄存器列表定义主要应用在堆栈操作或多寄存器传送中,即使用该伪指令定义的名称可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。,4.1.1 通用伪指令,指令示例:RegListRLISTR0-R5,R8;定义寄存器列表为RegList在程序中使用:STMFD SP!,RegList;存储列表到堆栈LDMIA R5,RegList;加载列表,4.1.1 通用伪指令,2.数据定义伪指令 数据定义伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪指令有如下几种:(1)DCB语法格式:标号 DCB表达式 DCB伪指令是字节分配内存单元伪指令,用来分配一片连续的字节存储单元并用伪指令中指定的数值或字符初始化。其中,数值范围为0255,DCB也可用“=”代替。,4.1.1 通用伪指令,指令示例:String DCB“This is a test!”;分配一片连续的字节存储单元并初始化。DATA2 DCB 15,25,62,00;为数字常量15,25,62,00分片内存单元,4.1.1 通用伪指令,(2)DCW(或DCWU)语法格式:标号DCW(或DCWU)表达式 DCW(或DCWU)伪指令是为半字分配内存单元,其中,表达式可以为程序标号或数字表达式。伪指令DCW用于为半字分配一段半字对准的内存单元,并用指定的数据初始化;伪指令DCWU用于为半字分配一段可以非半字对准的内存单元,并用指定的数据初始化。,4.1.1 通用伪指令,指令示例:DATA1 DCW 1,2,3;分配一片连续的半字存储单元并初始化为1,2,3。DATA2 DCWU 45,0 x2a*0 x2a;分配一片非半字对准存储单元并初始化。,4.1.1 通用伪指令,(3)DCD(或DCDU)语法格式:标号 DCD(或DCDU)表达式 DCD(或DCDU)伪指令是为字分配内存单元伪指令,其中,表达式可以为程序标号或数字表达式。DCD也可用“&”代替。伪指令DCD用来为字分配一段对准的内存单元,并用指定的数值或标号初始化;伪指令DCDU用来为字分配一段可以非对准的内存单元,并用指定的数值或标号初始化。,4.1.1 通用伪指令,指令示例:DATA1 DCD 4,5,6;分配一片连续的字存储单元并初始化。DATA2 DCDU LOOP;为LOOP标号的地址值分配一个内存单元。,4.1.1 通用伪指令,(4)DCFD(或DCFDU)和DCFS(或DCFSU)语法格式:标号 伪指令 表达式DCFD(或DCFDU)和DCFS(或DCFSU)都是为浮点数分配内存单元的伪指令。DCFD用于为双精度的浮点数分配一段字对准的内存单元,并用指定的数据初始化,每个双精度的浮点数占两个字单元;DCFDU用于为双精度的浮点数分配一段非字对准的内存单元,并用指定的数据初始化,每个双精度的浮点数占两个字单元;DCFS用于为单精度的浮点数分配一段字对准的内存单元,并用指定的数据初始化,每个单精度的浮点数占一个字单元;DCFSU用于为单精度的浮点数分配一段非字对准的内存单元,并用指定的数据初始化,每个单精度的浮点数占一个字单元。,4.1.1 通用伪指令,指令示例:FLO1 DCFD2E115,-5E7;分配一段字对准存储单元并初始化为指定的双精度数为2E115,-5E7。FLO2 DCFDU22,1E2;分配一段非字对准存储单元并初始化为指定的双精度数为22,1E2。FLO3 DCFS2E5,-5E7;分配一段非字对准存储单元并初始化为指定的单精度数为2E5,-5E-7。,4.1.1 通用伪指令,(5)DCQ(或DCQU)语法格式:标号 DCQ(或DCQU)表达式 DCQ(或DCQU)伪指令是为双字分配内存单元的伪指令。伪指令DCQ用于为双字分配一段字对准的内存单元,并用指定的数据初始化;伪指令DCQU用于为双字分配一段可以非字对准的内存单元,并用指定的数据初始化。指令示例:DATA1DCQ100;分配一片连续的存储单元并初始化为指定的值。,4.1.1 通用伪指令,(6)MAP和FILED语法格式:MAP表达式,基址寄存器 标号 FIELD 表明数据字节数的数值MAP和FILED是内存表定义伪指令。伪指令MAP用于定义一个结构化的内存表的首地址,MAP也可用“”代替;伪指令FIELD用于定义内存表中的数据的长度。FILED也可用“#”代替。,4.1.1 通用伪指令,表达式可以为程序中的标号或数学表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址,当该选项存在时,内存表的首地址为表达式的值与基址寄存器的和。注意MAP和FIELD伪指令仅用于定义数据结构,并不实际分配存储单元。,4.1.1 通用伪指令,指令示例:MAP0 x10,R1;定义内存表首地址的值为R1+0 x10。DATA1FIELD4;为数据DATA1定义4字节长度DATA2FIELD16;为数据DATA1定义16字节长度,4.1.1 通用伪指令,(7)SPACE语法格式:标号SPACE 分配的内存单元字节数 SPACE伪指令是内存单元分配伪指令,用于分配一片连续的存储区域并初始化为0,SPACE也可用“”代替。指令示例:DATASPA SPACE100;为DATASPA分配100个存储单元;并初始化为0,4.1.1 通用伪指令,3.汇编控制伪指令汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条:(1)MACRO、MEND和MEXIT语法格式:MACRO$标号宏名$参数1,$参数2,语句段MEXIT语句段MENDMACRO、MEND和MEXIT都是宏定义指令。,4.1.1 通用伪指令,伪指令MACRO定义一个宏语句段的开始;伪指令MEND定义宏语句段的结束;伪指令MEXIT可以实现从宏程序段的跳出。宏指令可以使用一个或多个参数,当宏指令被展开时,这些参数被相应的值替换。MACRO、MEND伪指令可以嵌套使用。宏是一段功能完整的程序,能够实现一个特定的功能,在使用中可以把它视为一个子程序。在其他程序中,可以调用宏完成某个功能。,4.1.1 通用伪指令,调用宏是通过调用宏的名称来实现的。宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销,因此,在代码较短且需要传递的参数较多时,可以使用宏指令代替子程序。调用宏的好处是不占用传送参数的寄存器,不用保护现场。,4.1.1 通用伪指令,指令示例:MACRO;定义宏$DATA1 MAX$N1,$N2;宏名称是MAX,主标号是$DATA1,两个参数语句段;语句段$DATA1.MAY1;非主标号,由主标号构成语句段;语句段$DATA1.MAY2;非主标号,由主标号构成MEND;宏结束,4.1.1 通用伪指令,(2)IF、ELSE、ENDIF语法格式:IF 逻辑表达式语句段1ELSE语句段2ENDIFIF、ELSE、ENDIF伪指令是条件分支伪指令,能根据条件的成立与否决定是否执行某个语句。伪指令IF可以对条件进行判断;伪指令ELSE产生分支;伪指令ENDIF定义分支结束。当IF后面的逻辑表达式为真,则执行语句段1,否则执行语句段2。其中,ELSE及语句段2可以没有,此时,当IF后面的逻辑表达式为真,则执行指令序列1,否则继续执行后面的指令。IF、ELSE、ENDIF伪指令可以嵌套使用。,4.1.1 通用伪指令,指令示例:IF R0=0 x10;判断R0中的内容是否是0 x10ADD R0,R1,R2;如果R0=0 x10,则执行R0=R1+R2ELSEADD R0,R1,R3;如果R0 0 x10,则执行R0=R1+R3ENDIF,4.1.1 通用伪指令,(3)WHILE、WEND语法格式:WHILE逻辑表达式语句段WENDWHILE、WEND伪指令是条件循环伪指令,能根据条件的成立与否决定是否循环执行某个语句段。伪指令WHILE对条件进行判断,满足条件循环,不满足条件结束循环;伪指令WEND定义循环体结束。当WHILE后面的逻辑表达式为真,则执行语句段,该语句段执行完毕后,再判断逻辑表达式的值,若为真则继续执行,一直到逻辑表达式的值为假。,4.1.1 通用伪指令,指令示例:GBLACou1;声明一个全局的数学变量,变量名为CounterCou1 SETA1;为Cou1赋值1WHILE Cou1 10;判断WHILECounter 10进入循环ADD R1,R2,R3;循环执行语句Cou1 SETA Cou1+1;每次循环Cou1加1WEND;执行ADD R1,R2,R3语句10次后,结束循环。在应用WHILE、WEND伪指令时要注意:用来进行条件判断的逻辑表达式必须是编译程序能够判断的语句,一般应该是伪指令语句。,4.1.1 通用伪指令,4.其他杂类伪指令 下面是一些比较重要的杂类伪指令,这些杂类伪指令在汇编程序中经常会被使用,包括以下几条:(1)ALIGN语法格式:ALIGN表达式,偏移量 ALIGN伪指令是地址对准伪指令,可通过插入字节使存储区满足所要求的地址对准。其中,表达式的值用于指定对准方式,可能的取值为2n,0n31,如果不选表达式,则默认字对准;偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:2n偏移量。,4.1.1 通用伪指令,指令示例:B STARTADD R0,R1,R2;正常语句DATA1 DCB“Ertai”;由于插入5个字节的存储区,地址不对准ALIGN 4;使用伪指令确保地址对准START LDR R5,R6;否则此标号不对准,4.1.1 通用伪指令,(2)AREA语法格式:AREA段名属性1,属性2,AREA伪指令是段指示伪指令,用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用“|”括起来,如|1_test|。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。,4.1.1 通用伪指令,AREA常用的属性如下:CODE属性:用于定义代码段,默认为READONLY。DATA属性:用于定义数据段,默认为READWRITE。READONLY属性:指定本段为只读,代码段默认为READONLY。READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。,4.1.1 通用伪指令,AREA常用的属性如下:ALIGN属性:使用方式为ALIGN 表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为031,相应的对齐方式为2表达式次方。COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。,4.1.1 通用伪指令,指令示例:AREAExample1,CODE,READONLY;定义了一个代码段,段名为Example1,属性为只读。,4.1.1 通用伪指令,(3)CODE16、CODE32语法格式:CODE16CODE32CODE16和CODE32伪指令是代码长度定义伪指令。若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令定义后面的代码编译成16位的Thumb指令,CODE32伪指令定义后面的代码编译成32位的ARM指令。,4.1.1 通用伪指令,指令示例:AREAExample1,CODE,READONLYCODE32;定义后面的指令为32位的ARM指令LDRR0,NEXT1;将跳转地址放入寄存器R0BXR0;程序跳转到新的位置执行,并将处理器切换到Thumb工作状态CODE16;定义后面的指令为16位的Thumb指令NEXTLDRR3,0 x3FFEND;程序结束,4.1.1 通用伪指令,(4)ENTRY语法格式:ENTRY ENTRY伪指令是程序入口伪指令。在一个完整的汇编程序中至少要有一个ENTRY,编译程序在编译连接时依据程序入口进行连接。在只有一个入口时,编译程序会把这个入口的地址定义为系统复位后的程序起始点。但在一个源文件里最多只能有一个ENTRY。指令示例:AREA Example1,CODE,READONLYENTRY;程序的入口处,4.1.1 通用伪指令,(5)END语法格式:END END伪指令是编译结束伪指令,用于通知编译器已经到了源程序的结尾,每个汇编语言的源程序都必须有一个END伪指令定义源程序结尾。编译程序检测到这个伪指令后,不再对后面的程序编译。指令示例:AREAExample1,CODE,READONLYEND;程序结束,4.1.1 通用伪指令,(6)EQU语法格式:名称 EQU表达式,类型 EQU伪指令是赋值伪指令,用于为程序中的常量、标号等定义一个等效的字符名称。名称为EQU伪指令定义的字符名称,当表达式为32位的常量时,可以指定表达式的数据类型,可以有以下三种类型:CODE16、CODE32和DATA。,4.1.1 通用伪指令,指令示例:TestEQU50;定义标号Test的值为50DATA1 EQU 0 x55,CODE32;定义DATA1的值为0 x55且该处为32位的ARM指令,4.1.1 通用伪指令,(7)GET和INCBIN语法格式:GET 文件名INCBIN 文件名 GET和INCBIN伪指令是文件引用伪指令。伪指令GET声明包含另一个源文件,并将被包含的源文件在当前位置进行汇编处理;伪指令INCBIN声明包含另一个源文件,在INCBIN处引用这个文件但不汇编。,4.1.1 通用伪指令,指令示例:AREA Example1,CODE,READONLYGET File1.s;包含文件File1.s,并编译INCBIN File2.dat;包含文件File2.s,不编译GETF:EX File3.s;包含文件File3.s,并编译END,4.1.2 与ARM指令相关的伪指令,与ARM指令相关的伪指令共有4条。这4条伪指令和通用伪指令不同,在程序编译过程中,编译程序会为这4条指令产生代码,但这些代码不是它们自己的代码,所以尽管它们可以产生代码,但还是伪指令。ADR伪指令ADRL伪指令LDR伪指令NOP,4.1.2 与ARM指令相关的伪指令,1.ADR伪指令语法格式:ADRcondRd,语句标号+数值表达式;其中Rd是目标寄存器,为R0R15。ADR伪指令是把地址加载到寄存器中的伪指令,这个地址可以是基于PC相对偏移的地址值,也可以是基于寄存器相对偏移的地址值读取到寄存器中。对偏移的地址值限定的范围是:字对准时,不得超过1020B;非字对准时,不得超过255B。指令示例:ADR R1,LOOP;把LOOP处绝对地址加载给R1ADR R1,LOOP+0 x10;把LOOP+0 x10处绝对地址加载给R1,4.1.2 与ARM指令相关的伪指令,2.ADRL伪指令语法格式:ADRcondRd,语句标号+数值表达式;其中Rd是目标寄存器,为R0R15。ADRL伪指令是把长地址加载到寄存器中的伪指令,这个地址可以是基于PC相对偏移的地址值,也可以是基于寄存器相对偏移的地址值读取到寄存器中。对偏移的地址值限定的范围是:字对准时,不得超过256K;非字对准时,不得超过64K。指令示例:ADRL R1,0 x10;把距离程序开始处16个地址单元处的绝对地址加载给R1。,4.1.2 与ARM指令相关的伪指令,3.LDR伪指令语法格式:LDRcondRd,=数值表达式;加载数字常量LDRcondRd,=语句标号+数值表达式;加载地址LDR伪指令是把一个数字常量或一个地址加载到寄存器伪指令。LDR伪指令主要用于以下两个目的:一是用于MOV和MVN指令中,若立即数由于超出范围而不能加载到寄存器中时,产生文字常量;另一个是将程序相对偏移量或一个标号所对应的地址加载到寄存器中。,4.1.2 与ARM指令相关的伪指令,指令示例:LDR R1,=0 x20;加载0 x20到R1中;汇编器汇编成MOV R1,#0 x20LDR R1,=0 x101;加载0 x101到R1中;汇编器汇编成LDR R1,PC,offsect_data1 data1 DCD 0 x101,4.1.2 与ARM指令相关的伪指令,4.NOP语法格式:NOP NOP伪指令是空操作指令,在汇编时将被编译成一条无效指令,如MOV R0,R0,占用32位代码空间。NOP伪指令不影响CPSR中的条件标志位。,4.1.2 与ARM指令相关的伪指令,指令示例:ADDRES1 LDR R1,=ADDRES2;把ADDRES2地址加载给R1 ADR R2,ADDRES1;把ADDRES1地址加载给R2 SUB R3,R1,R2;相减 ADDRES2 NOP;空操作,4.1.3 与Thumb指令相关的伪指令,与Thumb指令相关的伪指令共有3条,这些伪指令必须出现在Thumb程序段。ADR伪指令LDR伪指令NOP,4.1.3 与Thumb指令相关的伪指令,1.ADR伪指令语法格式:ADRcondRd,语句标号+数值表达式;其中Rd是目标寄存器,为R0R7。ADR伪指令是把地址加载到低端寄存器中的伪指令,这个地址必须是基于PC相对偏移的地址值。偏移必须向前偏移,偏移量不大于1KB,且该指令只可以加载字对准的地址。,4.1.3 与Thumb指令相关的伪指令,指令示例:ADR R0,LOOP;把LOOP处绝对地址;加载给R0ADR R1,LOOP+0 x40*2;把LOOP+0 x40*2处;绝对地址加载给R1 ALIGNLOOP ADD R2,R0,R1,4.1.3 与Thumb指令相关的伪指令,2.LDR伪指令语法格式:LDRcondRd,=数值表达式;加载数字常量LDRcondRd,=语句标号+数值表达式;加载地址 LDR伪指令是把一个数字常量或一个地址加载到低端寄存器伪指令。如果所加载的是一个32位的数字常量,则编译程序就可以把这条语句编译成一条MOV指令,如果不能用MOV指令来表达,则编译成一条LDR指令。如果所加载的是地址的话,编译程序会把这条语句编译成LDR指令。,4.1.3 与Thumb指令相关的伪指令,在使用LDR指令替代伪指令时,编译程序先把数据(或地址)存放在数据缓冲区内,在执行LDR指令时,从缓冲区读出这个数据加载到寄存器中去。因此,在使用这条伪指令时,要为程序创建数据缓冲区。指令示例:LDR R1,=0 xFFE;加载0 xFFE到R1中;汇编器汇编成MOV R1,#0 xFFELDR R1,=START;加载START处的地址到R1中,4.1.3 与Thumb指令相关的伪指令,3.NOP语法格式:NOPNOP伪指令是空操作指令,在汇编时将被编译成一条无效指令,如MOV R0,R0,占用32位代码空间。,4.2 汇编语言的语句格式,汇编语言的源程序主要组成:指令伪指令语句标号注释,4.2.1 书写格式,ARM(Thumb)汇编语言的语句格式为:语句标号 指令或伪指令;注释1.语句标号 语句标号可以大小写字母混合使用,可以使用数字和下划线。语句标号不能与指令助记符、寄存器、变量名同名。2.指令和伪指令 指令助记符和伪指令助记符可以大写,也可以小写,但不能大小写混合使用。指令助记符和后面的操作数寄存器之间必须有空格,不可以在这之间使用逗号。3.注释 汇编器在编译时,当发现一个分号后,把后面的内容解释为注释,不予以编译。,4.2.1 书写格式,举例:AREA EXAMPLE1,CODE,READONLY;EXAMPLE1程序段代码段,只读属性,4.2.2 汇编语言中表达式和运算符,在汇编语言程序设计中,经常使用各种符号代替地址、变量和常量等,以增加程序的可读性。1.变量ARM(Thumb)汇编程序所支持的变量形式有3种:数字变量逻辑变量字符串变量变量在编译过程中可能被改变。,4.2.2 汇编语言中表达式和运算符,(1)数字变量用于在程序的运行中保存数字值,数字变量的取值范围不能超过一个32位数所能表达的范围。全局数字变量使用伪指令GBLA定义;局部数字变量使用伪指令LCLA定义;数字变量使用伪指令SETA赋值。,4.2.2 汇编语言中表达式和运算符,(2)逻辑变量用于在程序的运行中保存逻辑值,逻辑值只有两种取值情况:真或假。全局逻辑变量使用伪指令GBLL定义;局部逻辑变量使用伪指令LCLL定义;逻辑变量使用伪指令SETA赋值。,4.2.2 汇编语言中表达式和运算符,(3)字符串变量用于在程序的运行中保存一个字符串.全局串变量使用伪指令GBLS定义;局部串变量使用伪指令LCLS定义;串变量使用伪指令SETS赋值。串变量需要使用双引号包含。,4.2.2 汇编语言中表达式和运算符,(4)变量代换程序中的变量可通过代换操作取得一个常量。代换操作符为“$”。如果在数字变量前面有一个代换操作符“$”,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“$”后的数字变量;如果在逻辑变量前面有一个代换操作符“$”,编译器会将该逻辑变量代换为它的取值(真或假);如果在字符串变量前面有一个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量。,4.2.2 汇编语言中表达式和运算符,指令示例:LCLSString1;定义局部字符串变量String1和String2LCLSString2String1 SETS“pen!”String2 SETS“This is a$String1”;字符串变量S2的值为“This is a Test!”,4.2.2 汇编语言中表达式和运算符,2.数字表达式及运算符数字表达式包括数字、数字常量、数字变量、数字运算符和括号构成。表达式的结果不能超过一个32位数的表达范围。(1)数字形式可以:十进制十六进制N进制ASCII,4.2.2 汇编语言中表达式和运算符,若是十进制,在表达的时候可以直接表达,例如:1234、56789。若是十六进制,有两种表达方法。一种是在数值前加“0 x”另一种是在数值前加“&”。例如:0 x12A,&FF00。,4.2.2 汇编语言中表达式和运算符,若是N进制:N是一个29之间的整数。表示方法是n_数值。例如:2_01101111是一个二进制数字8_54231067是一个八进制数字。,4.2.2 汇编语言中表达式和运算符,若是ASCII表达:有些值可以使用ASCII表达。例如:A表达A的ASCII码。例如:MOV R1,#A等同于MOV R1,#0 x41。,4.2.2 汇编语言中表达式和运算符,(2)数字常量是一个32位的整数。可以使用伪指令EQU定义一个数字常量,并且定义后不能改变。(3)数字变量是被定义变量的数字。,4.2.2 汇编语言中表达式和运算符,(4)数字运算符是表明两个表达式之间的关系。在数字表达式中,操作符有以下几种:算术运算符“”加“”减“”乘“/”除“MOD”取余数,4.2.2 汇编语言中表达式和运算符,以A和B表示两个数字表达式为例:AB表示A与B的和。AB表示A与B的差。AB表示A与B的乘积。A/B表示A除以B的商。A:MOD:B表示A除以B的余数。,4.2.2 汇编语言中表达式和运算符,移位运算符“ROL”、“ROR”、“SHL”及“SHR”以A和B表示两个数字表达式,以上的移位运算符代表的运算如下:A:ROL:B表示将A循环左移B位。A:ROR:B表示将A循环右移B位。A:SHL:B表示将A左移B位。A:SHR:B表示将A右移B位。,4.2.2 汇编语言中表达式和运算符,逻辑运算符“AND”、“OR”、“NOT”及“EOR”以A和B表示两个数字表达式,以上的按位逻辑运算符代表的运算如下:A:AND:B表示将A和B按位作逻辑与的操作。A:OR:B表示将A和B按位作逻辑或的操作。A:EOR:B 表示将A和B按位作逻辑异或的操作。NOT:B表示将B按位作逻辑非的操作。,4.2.2 汇编语言中表达式和运算符,3.逻辑表达式及运算符 逻辑表达式包括逻辑值、逻辑变量、逻辑操作符、关系操作符和括号构成,其表达式的运算结果为真或假。与逻辑表达式相关的运算符如下:(1)逻辑值:只有TRUE或FALSE。(2)逻辑变量:可以用伪指令定义逻辑变量。(3)逻辑运算符:包括“LAND”、“LOR”、“LNOT”及“LEOR”运算符,他们在运算时优先权较低。,4.2.2 汇编语言中表达式和运算符,以A和B表示两个逻辑表达式,以上的逻辑运算符代表的运算如下:A:LAND:B 表示将A和B 作逻辑与的操作。A:LOR:B 表示将A和B作逻辑或的操作。A:LEOR:B 表示将A和B作逻辑异或的操作。LNOT:B 表示将B作逻辑非的操作。,4.2.2 汇编语言中表达式和运算符,(4)关系运算符:关系运算符所关联的两个操作数必须形式相同,运算结果应该是一个逻辑值。包括“=”、“”、“=”、“”运算符。以A和B表示两个逻辑表达式,以上的运算符代表的运算如下:A=B表示A等于B。A B表示A大于B。A=B表示A大于等于B。A B表示A不等于B。,4.2.2 汇编语言中表达式和运算符,指令示例:MOV R5,#0 xFF00:MOD:0 xF:ROL:2;R5寄存器里的内容为0 x00IF R5:LAND:R6=R7MOV R0,#0 x00ELSEMOV R0,#0 xFF;如果R5R6=R7则R0=0 x00;否则,R0=0 xFF,4.2.2 汇编语言中表达式和运算符,4.字符串表达式及运算符 字符串表达式包括字符串常量、字符串变量、运算符和括号构成。编译器所支持的字符串最大长度为512字节。(1)字符串:用双引号包含在内的一系列字符称为字符串。(2)字符串变量:被定义为变量的字符串称为字符串变量,4.2.2 汇编语言中表达式和运算符,(3)单目运算符:是只涉及一个字符串的运算符,在串运算中,单目运算符有较高的优先权。单目运算符如表4-1所示。(4)双目运算符:涉及两个表达式,其中至少有一个是字符串。双目运算符如表4-2所示。,4.2.2 汇编语言中表达式和运算符,表4-1 单目运算符,4.2.2 汇编语言中表达式和运算符,表4-2 双目运算符,4.2.2 汇编语言中表达式和运算符,指令实例:GBLS STRING;定义字符串STRINGSTRING SETS:CHR:65;为STRING赋值;(65是A的ASCII)GBLS STRING2;定义字符串STRING2STRING2 SETS“EMBEDDED SYSTEM”;为STRING2赋值GBLS STRING3;定义字符串STRING3STRING3 SETS STRING2:LEFT:8;将值EMBEDDED赋值给字符串STRING3,4.2.2 汇编语言中表达式和运算符,5.以寄存器和程序计数器(PC)为基址的表达式及运算符 常用的与寄存器和程序计数器(PC)相关的表达式及运算符如下:(1)BASE运算符 BASE运算符返回基于寄存器的表达式中寄存器的编号,其语法格式如下:BASE:A其中,A为与寄存器相关的表达式。,4.2.2 汇编语言中表达式和运算符,(2)INDEX运算符 INDEX运算符返回基于寄存器的表达式中相对于其基址寄存器的偏移量,其语法格式如下:INDEX:A其中,A为与寄存器相关的表达式。,4.2.2 汇编语言中表达式和运算符,6.运算符的优先级 在对汇编程序进行编译时,运算中一般遵循的基本规则是:先计算括号内,后计算括号外;在有多个操作符时,顺序和运算符有关;单目运算符较双目运算符优先;在相同优先权情况下,从左到右运算。运算符的优先级如表4-3所示。,4.2.2 汇编语言中表达式和运算符,表4-3 运算符优先级,4.3 汇编程序应用,4.3.1 汇编程序基本结构下面是一个汇编语言源程序的基本结构:AREA example,CODE,READONLY;定义代码块为exampleENTRY;程序入口StartMOV R0,#40;R0=40MOV R1,#16;R1=16 ADD R2,R0,R1;R2=R0+R1MOV R0,#0 x18;传送到软件中断的参数LDR R1,=0 x20026;传送到软件中断的参数SWI 0 x123456;通过软件中断指令返回END;文件结束,4.3.1 汇编程序基本结构,AREA 伪指令定义一个段,并说明所定义段的相关属性,本例定义一个名为 example 的代码段,属性为只读。ENTRY 伪指令标识程序的入口点,接下来为语句段。执行主代码后,通过返回控制终止应用程序并返回到DEBUG,通过使用软件中断指令实现了返回。在程序的末尾为 END 伪指令,该伪指令通知编译器停止对源文件的处理,每一个汇编程序段都必须有一条END伪指令,指示代码段的结束。,4.3.2 子程序调用,2.在ARM汇编语言程序中,子程序的调用一般是通过BL指令来实现的。3.指令格式:BL子程序名 该指令在执行时完成如下操作:将子程序的返回地址存放在连接寄存器LR中,同时将程序计数器PC指向子程序的入口点,当子程序执行完毕需要返回调用处时,只需要将存放在LR中的返回地址重新拷贝给程序计数器PC(即:使用指令MOV PC,LR)。,4.3.2 子程序调用,习惯上用寄存器R0R3来存放送到子程序的参数,然后从子程序返回时存放返回的结果给调用者。下面给出的子程序,减4个参数的值,用R0返回结果(即实现R0=R0-R1-R2-R3)。,4.3.2 子程序调用,AREAInit,CODE,READONLY;定义一个代码段ENTRY;定义一个程序入口LOOP1MOV R0,#412;给参数R0赋值680MOV R1,#106;给参数R1赋值25MOV R2,#64;给参数R2赋值101MOV R3,#195;给参数R3赋值91BL SUB1;调用子程序SUB1,同时将子程序的返回;地址存放在连接寄存器R14(LR)中。MOV R0,#0 x18;传送到软件中断的参数LDR R1,=0 x20026;传送到软件中断的参数SWI 0 x123456;通过软件中断指令返回SUB1SUB R0,R0,R1;子程序代码SUB R0,R0,R2SUB R0,R0,R3MOV PC,LR;从子程序返回END,4.4 汇编语言与C/C+的混合编程,在应用系统的程序设计中,若所有的编程任务均用汇编语言来完成,其工作量是可想而知的。事实上,ARM体系结构支持C/C以及与汇编语言的混合编程,在一个完整的程序设计的中,除了初始化部分用汇编语言完成以外,其主要的编程任务一般都用C/C+完成。汇编语言与C/C+的混合编程通常有以下几种方式:在C/C代码中嵌入汇编指令。在汇编程序和C/C的程序之间进行变量的互访。汇编程序、C/C程序间的相互调用。,4.4 汇编语言与C/C+的混合编程,在以上的几种混合编程技术中,必须遵守一定的调用规则:这里所指的是ATPCS规则,PCS即Procedure Call Standard(过程调用规范),ATPCS即ARM-THUMB procedure call standard。PCS规定了应用程序的函数可以如何分开地写,分开地编译,最后将它们连接在一起,所以它实际上定义了一套有关过程(函数)调用者与被调用者之间的协议。,4.4 汇编语言与C/C+的混合编程,PCS强制实现如下约定:调用函数如何传递参数(即压栈方法,以何种方式存放参数),被调用函数如何获取参数,以何种方式传递函数返回值。PCS的制订是一系列指标的“tradeoff(折衷)”(因为很大程度上涉及系统的一些性能),如:会涉及生成代码的大小,调试功能的支持,函数调用上下文处理速度以及内存消耗等。当然,通过编译

    注意事项

    本文(嵌入式系统原理及应用教程第4章.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开