




已阅读5页,还剩40页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章arm处理器指令概述,本章重点,常用arm指令 arm汇编程序编程实例 汇编与c语言混合编程 ads集成开发环境,本章内容,4.1 arm 微处理器的指令的分类与格式 4.2 arm 指令的寻址方式 4.3 常用arm指令 4.4 汇编语言的程序结构及在ads环境下调试 4.5 汇编语言与 c/c+的混合编程,4.1 arm 微处理器的指令的分类与格式,arm微处理器的指令集是加载/存储型的,也即指令集仅能处理寄存器中的数据,而且处理结果都要放回寄存器中,而对系统存储器的访问则需要通过专门的加载/存储指令来完成。 arm微处理器的指令集可以分为跳转指令、数据处理指令、程序状态寄存器(psr)处理指令、加载/存储指令、协处理器指令和异常产生指令六大类。,4.2 arm 指令的寻址方式,所谓寻址方式就是处理器根据指令中给出的地址信息来寻找物理地址的方式。目前arm指令系统支持如下几种常见的寻址方式。 4.2.1 立即寻址 立即寻址也叫立即数寻址,这是一种特殊的寻址方式,操作数本身就在指令中给出,只要取出指令也就取到了操作数。这个操作数被称为立即数,对应的寻址方式也就叫做立即寻址。例如以下 指令: add r0,r0,1 ;r0r01 add r0,r0,0x3f ;r0r00x3f 在以上两条指令中,第二个源操作数即为立即数,要求以“”为前缀,对于以十六进制表示的立即数,还要求在“”后加上“0x”或“&”。,4.2 arm 指令的寻址方式,4.2.2 寄存器寻址 寄存器寻址就是利用寄存器中的数值作为操作数,这种寻址方式是各类微处理器经常采用的一种方式,也是一种执行效率较高的寻址方式。以下指令: add r0,r1,r2 ;r0r1r2 该指令的执行效果是将寄存器r1和r2的内容相加,其结果存放在寄存器r0中。 4.2.3 寄存器间接寻址 寄存器间接寻址就是以寄存器中的值作为操作数的地址,而操作数本身存放在存储器中。例如以下指令: add r0,r1,r2 ;r0r1r2 ldr r0,r1 ;r0r1 str r0,r1 ;r1r0 在第一条指令中,以寄存器 r2 的值作为操作数的地址,在存储器中取得一个操作数后与 r1 相加,结果存入寄存器 r0 中。 第二条指令将以 r1 的值为地址的存储器中的数据传送到 r0 中。 第三条指令将 r0 的值传送到以 r1 的值为地址的存储器中。,4.2 arm 指令的寻址方式,4.2.4 基址变址寻址 基址变址寻址就是将寄存器(该寄存器一般称作基址寄存器)的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。变址寻址方式常用于访问某基地址附近的地址单元。采用变址寻址方式的指令常见有以下几种形式,如下所示: ldr r0,r1,#4 ;r0r14 ldr r0,r1,#4! ;r0r14、r1r14 ldr r0,r1 ,#4 ;r0r1、r1r14 ldr r0,r1,r2 ;r0r1r2 在第一条指令中,将寄存器 r1 的内容加上 4 形成操作数的有效地址,从而取得操作数存入寄存器 r0 中。 在第二条指令中,将寄存器 r1 的内容加上 4 形成操作数的有效地址,从而取得操作数存入寄存器 r0 中,然后,r1 的内容自增 4 个字节。 在第三条指令中,以寄存器 r1 的内容作为操作数的有效地址,从而取得操作数存入寄存器 r0中,然后,r1 的内容自增 4 个字节。 在第四条指令中,将寄存器 r1 的内容加上寄存器 r2 的内容形成操作数的有效地址,从而取得操作数存入寄存器 r0 中。,4.2 arm 指令的寻址方式,4.2.5 多寄存器寻址 采用多寄存器寻址方式,一条指令可以完成多个寄存器值的传送。这种寻址方式可以用一条指令完成传送最多 16 个通用寄存器的值。以下指令: ldmia r0,r1,r2,r3,r4 ;r1r0 ;r2r04 ;r3r08 ;r4r012 该指令的后缀 ia 表示在每次执行完加载/存储操作后,r0 按字长度增加,因此,指令可将连续存储单元的值传送到 r1r4。 4.2.6 相对寻址 与基址变址寻址方式相类似,相对寻址以程序计数器 pc 的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的调用和返回,跳转指令 bl 采用了相对寻址方式: bl next ;跳转到子程序 next 处执行 next mov pc,lr ;从子程序返回,4.2 arm 指令的寻址方式,4.2.7 堆栈寻址 堆栈是一种数据结构,按先进后出(first in last out,filo)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。 当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(full stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(empty stack)。 同时,根据堆栈的生成方式,又可以分为递增堆栈(ascending stack)和递减堆栈(decending stack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式,arm 微处理器支持这四种类型的堆栈工作方式, 即: 满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。 满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。 空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成。,4.3 常用arm指令,4.3.1 内存访问指令 1. 基本指令 ldr:存储器memory中数据传送到寄存器register str:寄存器register中数据传送到存储器memory 例如: ldr r0, r1 ; r1作为指针,该指针指向的数存入r0 str r0, r1, #4 ; r1+4作为指针,r0的值存入该地址 str r0, r1, #4! ; 同上,并且r1 = r1 + 4 ldr r1, =0x08100000 ; 立即数0x08100000存到r1 ldr r1, r2, #4 ; r2+4作为指针,指向的值存入r1,并且r2=r2+4,4.3 常用arm指令,4.3.1 内存访问指令 2. 多字节存取指令 多字节存取指令常应用于堆栈操作。 ldm:存储器memory中数据传送到多个寄存器 stm:多个寄存器中的数据传送到存储器memory 例如: sub lr, lr, #4 ;lr4是异常处理完后应该返回的地方 stmfd sp!,r0-r12, lr ;保存r0r12和lr寄存器的值到堆栈并更新堆栈指针。 ldmfd sp!,r0-r12, pc ;从堆栈中恢复r0r12,返回地址赋给pc指针,使程序返回到异常发生前所执行的地方,标记用来使cpu退出异常模式,进入普通状态。,4.3 常用arm指令,4.3.2 算术运算指令 基本指令: add:加 sub:减 例如: add r0, r1, r2 ; r0 = r1 + r2 adds r0, r1, #0x80 ; r0 = r1 + 0x80,并设置状态寄存器 subs r0, r1,#2000 ; r0 = r1 2000,并设置状态寄存器,4.3 常用arm指令,4.3.3 逻辑运算指令 基本指令: and:与 orr:或 eor:异或 bic:位清0 例如: ands r0,r1,#0xff00 ; r0 = r1 and 0xff00,并设置状态寄存器 orr r0, r1, r2 ; r0 = r1 and r2 bics r0, r1, #0xff00 ; r0 = r1 and ! (0xff00) ands r0, r1, #0xffff00ff ; 错误,4.3 常用arm指令,4.3.4 mov指令 mov指令: 例如: mov r0, #8 ; r0 = 8 mov r0, r1 ; r0 = r1 mov不同于ldr、str指令,该指令可以在寄存器间赋值。 4.3.5比较指令 基本指令: cmp:比较两个操作数,并设置状态寄存器 例如: cmp r0, r1 ;计算r0- r1,并设置状态寄存器,判断r0是否大于、小于或等于r1 cmp r0, #0 ;,4.3 常用arm指令,4.3.6 跳转指令 基本指令: b:跳转 bl:跳转并将下一指令的地址存入lr寄存器 例如: loop1 b loop1 ; 跳到地址loop1处 bl sub1 ; 将下一指令地址写入lr,并跳至sub1 sub1 mov pc, lr ; 从sub1中返回,4.3 常用arm指令,4.3.7 条件执行指令 条件:状态寄存器中某一或某几个比特的值代表条件,对应不同的条件后缀cond。 例如: cmp r0, r1 ;比较r0和r1 blgt sub1 ;如果r0r1,跳转到sub1,否则不操作 ; ;一段循环代码 ldr r2, =8 ;r2 = 8 loop ;这里可以进行一些循环内的操作 subs r2, r2, #1 ;r2 = r2 1,并设置状态位 bne loop ;如果r2不等于0,则继续循环 ; mov r0, #1 ; r0 = 1 cmp r2, #8 ;比较r2和8 movlt r0, #2 ;如果r28,r0 = 2,4.4 汇编语言的程序结构及在ads环境下调试,在 arm(thumb)汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映象文件。 441 汇编语言程序结构 以下是一个汇编语言源程序的基本结构。 area init,code,readonly entry end ; 汇编语言源程序的基本结构,分号为注释 area ex2,code,readonly ;area指令定义一个名为ex2程序段,属性为只读,4.4 汇编语言的程序结构及在ads环境下调试,例4-1 定义一个代码段arm,其属性为只读,首先分别给3个变量赋值,给x、y赋两个值,给stack_top赋一个地址,程序代码如下,请阅读程序写出最后r0的值及调试程序及地址0x1000上的内容,程序名为test1.s。 area arm,code,readonly x equ 45 y equ 64 stack_top equ 0x1000 entry mov sp,#stack_top mov r0,#x str r0,sp mov r0,#y ldr r1,sp add r0,r0,r1 str r0,sp stop b stop end,4.4 汇编语言的程序结构及在ads环境下调试,442 汇编语言编辑、运行与调试 1、运行 ads1.2 集成开发环境,点击 file|new,在 new 对话框中,选择 project中的arm executable image 选项,在 project name 栏中输入项目的名称,按“确定”保存项目 。,4.4 汇编语言的程序结构及在ads环境下调试,2、 在新建的工程中,选择debug 版本,如图4-2,使用edit|debug settings 菜单对debug版本进行参数设置。 。,4.4 汇编语言的程序结构及在ads环境下调试,3、 在如图4-3 中,点击debug setting 按钮,弹出4-4 图,选中target setting 项,在post-linker 栏中选中arm fromelf 项。按ok 确定。这是为生成可执行的代码的初始开关。 。,4.4 汇编语言的程序结构及在ads环境下调试,4.4 汇编语言的程序结构及在ads环境下调试,4、在如图4-5 中,点击arm assembler ,在architecture or processer 栏中选arm9tdmi。这是要编译的cpu 核。 。,4.4 汇编语言的程序结构及在ads环境下调试,5、在如图4-6 中,点击arm c compliler ,在architecture or processer 栏中选arm9tdmi。这是要编译的cpu 核。 。,4.4 汇编语言的程序结构及在ads环境下调试,6、在如图4-7 中,点击arm linker ,在output 栏中设定程序的代码段地址,以及数据使用的地址。图中的ro base 栏中填写程序代码存放的起始地址,rw base 栏中填写程序数据存放的起始地址。该地址是属于sdram 的地址。 。,4.4 汇编语言的程序结构及在ads环境下调试,在options 栏中,如图4-8,image entry point 要填写程序代码的入口地址,其他保持不变,如果是在sdram 中运行,则可在0x0c0000000x0cffffff 中选值,这是16msdram 的地址,但是这里用的是起始地址,所以必须把你的程序空间给留出来,并且还要留出足够的程序使用的数据空间,而且还必须是4字节对齐的地址(arm 状态)。通常入口点image entry point 为0xc100000,ro_base 也为0xc100000。 。,4.4 汇编语言的程序结构及在ads环境下调试,在layout 栏中,如图4-9,在place at beginning of image 框内,需要填写项目的入口程序的目标文件名,如,整个工程项目的入口程序是44binit.s,那么应在object/symbol 处填写其目标文件名44binit.o,在section 处填写程序入口的起始段标号。它的作用是通知编译器,整个项目的开始运行,是从该段开始的。 。,4.4 汇编语言的程序结构及在ads环境下调试,7、在如图4-10 中,即在debug setting 对话框中点击左栏的arm fromelf 项,在output file name 栏中设置输出文件名*.bin,前缀名可以自己取,在output format 栏中选择plain binary,这是设置要下载到flash 中的二进制文件。图4-10 中使用的是test.bin. 。,4.4 汇编语言的程序结构及在ads环境下调试,8、装载文件test1.s,在如图4-11所示工程test1.mcp中file的空白处点击右键,选择菜单项add files,导入文件test1.s,并作图4-12的选项。 。,4.4 汇编语言的程序结构及在ads环境下调试,9、在ads1.2 集成开发环境(codewarrior for arm developer suite)选择菜单project|debug。 10、如果是模拟调试,选择axd中菜单optionsconfigure target选择armul,如图-11所示。 。,4.4 汇编语言的程序结构及在ads环境下调试,11、程序调试 (1)查看/修改存储器内容 在axd窗口中,点击processor views|memory,可以在memory start address输入存储器的起始地址,查看存储器某地址上的内容,双击某一数据,可以修改此存储单元的内容。 (2)在命令行窗口执行axd命令 在axd窗口中,点击system views|command line interface,在提示符下可以输入命令进行调试。 (3)监视变量变化 在axd窗口中,点击processor views|watch,用鼠标选中某变量,单击鼠标右键,在弹出的菜单中选中add to watch,此变量显示在watch窗口中。,4.4 汇编语言的程序结构及在ads环境下调试,(4)设置断点 将光标定位在要设置断点的某语句处,按f9键。调试的结果如图4-12所示,图中显示了断点、watch中寄存器的值、存储器从起始地址0x1000开始的存储内容。,4.5 汇编语言与 c/c+的混合编程,在应用系统的程序设计中,若所有的编程任务均用汇编语言来完成,其工作量是可想而知的,同时,不利于系统升级或应用软件移植,事实上,arm 体系结构支持 c/c+以及与汇编语言的混合编程,在一个完整的程序设计的中,除了初始化部分用汇编语言完成以外,其主要的编程任务一般都用c/c+ 完成。 汇编语言与c/c+的混合编程通常有以下几种方式: 1 在c/c+代码中嵌入汇编指令。 2在汇编程序和c/c+的程序之间进行变量的互访。 3汇编程序、c/c+程序间的相互调用。,4.5 汇编语言与 c/c+的混合编程,在以上的几种混合编程技术中,必须遵守一定的调用规则,如物理寄存器的使用、参数的传递等,这对于初学者来说,无疑显得过于烦琐。在实际的编程应用中,使用较多的方式是:程序的初始化部分用汇编语言完成,然后用c/c+完成主要的编程任务,程序在执行时首先完成初始化过程,然后跳转到c/c+程序代码中,汇编程序和c/c+程序之间一般没有参数的传递,也没有频繁的相互调用,因此,整个程序的结构显得相对简单,容易理解。 . c程序调用汇编程序 1c程序嵌入汇编指令 汇编指令以语句块形式嵌入在c程序的函数中,其使用格式为: _asm 汇编语句 汇编指令以函数形式嵌入在c程序的函数中,其使用格式为: _asm int 函数名(形式参数表) 汇编代码 ,4.5 汇编语言与 c/c+的混合编程,(1)汇编指令以语句块形式嵌入在c程序中 例如:在c程序中嵌入汇编语句的例子。 #include int add(int i,int j) int sum; _asm add sum,i,j return sum; int main() int x,y; scanf(“%d %d“, 请建立一个工程,调试上述程序。,4.5 汇编语言与 c/c+的混合编程,(2)在c程序中调用以函数形式构成的汇编指令 c程序调用汇编程序时,汇编程序的书写也要遵循atpcs规则,以保证程序调用时参数正确传递。在c程序中调用汇编子程序的方法为:首先在汇编程序中使用export伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在c程序中使用extern关键字声明要调用的汇编子程序为外部函数。 例如:在一个汇编源文件中定义了如下求和函数。 export add ;声明add子程序将被外部函数调用 add ;求和子程序add add r0,r0,r1 mov pc,lr 在一个c程序的main()函数中对add汇编子程序进行了调用: extern int add (int x,int y); /声明add为外部函数 void main( ) int a=1,b=2,c; c=add(a,b); /调用add子程序 当main()函数调用add汇编子程序时,变量a、b的值会给了r0和r1,返回结果由r0带回,并赋值给变量c。函数调用结束后,变量c的值变成3。,4.5 汇编语言与 c/c+的混合编程,例如: 1、建立文件add.s,代码如下: export add area add,code,readonly entry add r0,r0,r1 mov pc,lr end 2、c程序代码为: #include extern int add(int x,int y); int main() int x,y; scanf(“%d %d“, ,4.5 汇编语言与 c/c+的混合编程,3、程序调试方法 (1)首先建立一个工程test (
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 重庆育儿知识培训中心课件
- 人教版八年级英语上册单元同步知识点与语法训练 unit8 section A
- 重庆应急急救知识培训课件
- 新解读《GB-T 18816-2014船用热交换器通 用技术条件》
- 重庆小学生安全知识培训课件
- 常见危险作业(特殊作业)安全管理精要
- 书面表达:环保、科技、传统文化、励志话语-2026年中考英语一轮复习
- 《英语教学理论与实践》课程介绍与教学大纲
- 醉酒后急救知识培训课件
- 外教君真人直播外语学习平台商业计划书
- 美容院股权分配协议书
- 《电子商务基础(第二版)》课件 第二章 电子商务交易模式
- 2025年交管12123驾驶证学法减分题库(含答案)
- 《中国高铁发展》课件
- 配电室防汛应急预案
- 2025年部编版小学二年级语文上册全册教案
- 高中主题班会 《铭记历史强国有我》课件-高一上学期爱国主义教育主题班会
- 2024年秋季新北师大版七年级上册数学全册教案设计
- 2025-2030年口红色彩创新设计行业跨境出海战略研究报告
- 2025年个体经营户劳务合同(五篇)
- 医院住院患者管理
评论
0/150
提交评论