【文档说明】ch4_ARM7TDMI汇编语言程序设计课件.ppt,共(81)页,2.624 MB,由我爱分享上传
转载请保留链接:https://www.ichengzhen.cn/view-44463.html
以下为本文档部分文字说明:
page2022/11/24西安邮电学院计算机系1第4章ARM7TDMI汇编语言程序设计page西安邮电学院计算机系22022/11/24第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序
设计的基本方法4.汇编语言和C语言交叉编程page西安邮电学院计算机系32022/11/24第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程page西安邮
电学院计算机系42022/11/241.汇编语言的基本概念程序设计语言是专门为计算机编程所配置的语言。它们按照形式与功能的不同可分为三种,即机器语言、汇编语言和高级语言。1.机器语言机器语言(MachineLanguage)是由0和1二进制代码书写和存储的指令与数据。它的特点是能被机器直接识别与
执行;程序所占内存空间较少。其缺点是难认、难记、难编、易错。page西安邮电学院计算机系52022/11/242.汇编语言汇编语言(AssemblyLanguage)是一种面向物理层操作的计算机语言,是一种采用助记符表示的程序设计语言,使用助记符
来表示指令的操作码和操作数,用标号或符号代表地址、常量或变量。汇编语言源程序汇编程序目标程序从机器角度看:汇编语言是一种面向物理层操作的计算机语言。不同的处理器类型,具有不同的汇编语言。使用汇编语言编写程序能够直接利用硬件系统的特性(如寄存器、标志、中断系统等),可直接对位、字节、字寄存
器或存储单元、I/O端口进行处理,同时也能直接使用CPU指令系统提供的各种寻址方式,编制出高质量的程序,这样的程序不但占用内存空间少,而且执行速度快。page西安邮电学院计算机系62022/11/243.高级语言高级语言(HighLevelLa
nguage)是脱离具体机器(即独立于机器)的通用语言,不依赖于特定计算机的结构与指令系统。用高级语言编写的源程序编译或解释程序目标程序page西安邮电学院计算机系72022/11/24第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇
编语言和C语言交叉编程page西安邮电学院计算机系82022/11/242.ARM汇编程序的组成与结构;文件名:TEST1.S;功能:实现字符串拷贝功能;说明:使用ARMulate软件仿真调试AREAExample1
,CODE,READONLY;声明代码段Example1numEQU20;设置拷贝字的个数ENTRY;标识程序入口CODE32;声明32位ARM指令STARTLDRR0,=src;R0指向源数据块LDRR1,
=dst;R1指向目的数据块MOVR2,#num;R2需要拷贝的数据个数wordcopyLDRR3,[R0],#4;从源数据块中取一个字,放入R3中,;R0=R0+4STRR3,[R1],#4;将R3中的数据存入
R1指向的存储;单元中,R1=R1+4SUBSR2,R2,#1;R2计数器减1BNEwordcopy;如果R2不为0,则转向wordcopy处使用‚;‛进行注释标号顶格写程序代码段page西安邮电学院计算机系92022
/11/24stopMOVR0,#0x18;程序运行结束返回编译器调试环境LDRR1,=0x20026SWI0x123456AREABlockData,DATA,READWRITE;数据段的名字BlockDataSrcDCD1,2,3,4,5,6,7,8
,1,2,3,4,5,6,7,8,1,2,3,4DstDCD0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0AREA|.extra|,NOINIT,READWRITE;未初始数据段的名字.extradataSP
ACE1024END;文件结束声明文件结束page西安邮电学院计算机系102022/11/242.0汇编语言程序格式汇编语言形式汇编语言源程序的组成汇编语言程序中常用的符号汇编语言程序中的表达
式和运算符page西安邮电学院计算机系112022/11/24汇编语言形式page西安邮电学院计算机系122022/11/24汇编语言程序中常用的符号在汇编语言程序设计中,经常使用各种符号表示变量、常量和地址组成:符号由大小写字母、数字以及下划线组成。大小写:符号区分大小写,同名的大、小写符号
会被编译器认为是两个不同的符号。唯一性:符号在其作用范围内必须唯一,即在其作用范围内不可有同名的符号。自定义的符号名不能与系统的保留字相同。不能同名:符号名不应与指令或伪指令同名。page西安邮电学院计算机系1320
22/11/241.程序中的变量变量的类型:数值变量逻辑变量字符串变量作用范围:全局变量局部变量page西安邮电学院计算机系142022/11/242.程序中的常量ARM(Thumb)汇编程序所支持的常量有数值常量、逻辑常量和字符串常量。数值常量一般
为32位的整数,当作为无符号数时,其取值范围为0~232-1;当作为有符号数时,其取值范围为-231~231-1。在ARM汇编语言中,使用EQU来定义数值常量。数值常量一经定义,其数值就不能再修改。page西安邮电学院计算机系152022/11/24数值常量有下列表示方式:十进制数:可以直接
表达如:1、2、345。十六进制数:有两种表达方法,使用前缀0x,如0x003、0x001C,或使用前缀&,如&10F、&134。这两种方法都是等效的。n进制数:形如n_XXX,其中n的范围是2到9,XXX是具体数值。如:8_247表示一个八进制数。ASCII的表示:有些值
可以使用ASCII表达,例如:‘A’表达A的ASCII码。指令:MOVR1,#’B’等同于MOVR1,#0x42。page西安邮电学院计算机系162022/11/24逻辑常量只有两种取值情况:{TRUE}和{FALSE},注意带大括号。字符串常量为一个固定的字符串,
一般用于程序运行时的信息提示。字符常量由单引号表示,包括C语言中的转义字符,如’\n’。字符串常量用双引号表示,也包括C语言中的转义字符如‚abcd\0xc\r”。page西安邮电学院计算机系172022/11/24汇编语言程序中的表达式和运算符数值表达式逻辑表达式字符串表达式表达式中各
元素运算次序的优先级如下:括号运算符的优先级最高。相邻的单目运算符的运算顺序为从右到左,单目运算符的优先级高于其它运算符。优先级相同的双目运算符的运算顺序为从左到右。page西安邮电学院计算机系182022/11/2
4汇编语言的语句格式[Label]Operation[Operand][;Comment]标号域操作助记符域操作数域注释域例:startMOVR0,#0x3F;将立即数传送到寄存器R0page西安邮电学院计算机系1
92022/11/24标号域(Label):作用:标号域用来表示指令的地址、变量、过程名、数据的地址和常量。开头:标号是一个自行设计的标识符或名称,语句标号可以是大小写字母混合,通常以字母开头,由字母、数字、下划线等组成
。要求:语句标号不能与寄存器名、指令助记符、伪指令(操作)助记符、变量名同名。位置:语句标号必须在一行的开头书写,不能留空格。page西安邮电学院计算机系202022/11/24操作助记符域(Operation):操作助记符域可以为指令、伪操作、宏指令
或伪指令的助记符。大小写要求:ARM汇编器对大小写敏感,在汇编语言程序设计中,每一条指令的助记符可以全部用大写、或全部用小写,但不允许在一条指令中大、小写混用。位置:所有的指令都不能在行的开头书写,必须在指令的前面有空格,然后再书写指令。格式:指令助记符和后面的操作数或操作寄存
器之间必须有空格,不可以在这之间使用逗号。page西安邮电学院计算机系212022/11/24操作数域(Operand):操作数域表示操作的对象,操作数可以是常量、变量、标号、寄存器名或表达式,不同对象之间
必须用逗号‚,‛分开。page西安邮电学院计算机系222022/11/24课堂练习判断指令格式正误AREAEX3,CODE,READONLYGBLADATADATASETA0x20ADDR0,R1,R2ADDR0
,R1,r2addR0,R1,r2AddR0,R1,r2前面必须有空格前面必须有空格DATA变量名前面不能留空格全部大写,正确寄存器小写,正确指令助记符小写,寄存器大写或小写,正确指令助记符大小写混合,不正确page西安邮电学院计算机系232022/11/242.1ARM汇编器的伪操
作在汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,其没有相对应的操作码,通常称这些特助指令助记符为伪操作。伪操作仅在汇编过程中起各种准备工作作用。ARM汇编中伪操作:•符号定义伪操作•数据定义伪操作•汇编控制伪操作•信息报告伪操作•
其它常用的伪操作page西安邮电学院计算机系242022/11/24符号定义伪操作符号定义伪操作用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的符号定义伪操作有如下几种:(1)GBL
A、GBLL、GBLS(2)LCLA、LCLL,LCLS(3)SETA、SETL、SETS(4)RLISTpage西安邮电学院计算机系252022/11/24各符号定义伪操作功能说明:GBLA:定义
一个全局的数值变量,并初始化为0GBLL:定义一个全局的逻辑变量,并初始化为FGBLS:定义一个全局字符串变量,并初始化为空LCLA:定义一个局部的数值变量,并初始化为0LCLL:定义一个局部的逻辑变量,并初始化
为FLCLS:定义一个局部字符串变量,并初始化为空SETA:给一个数值变量赋值;SETL:给一个逻辑变量赋值;SETS:给一个字符串变量赋值;page西安邮电学院计算机系262022/11/24使用示例:GBLAA1;定义一个全局的数值变量,变量名为A1A1SETA0x0F;将该变量
赋值为0x0FGBLLA2;定义一个全局的逻辑变量,变量名为A2A2SETL{TRUE};将该变量赋值为真GBLSA3;定义一个全局的字符串变量,变量名为A3A3SETS“Testing”;将该变量赋值为‚Testing”LCLAT4;声明一个局部的数值变
量,变量名为T4T4SETA0xaa;将该变量赋值为0xaapage西安邮电学院计算机系272022/11/24数据定义伪操作DCB:分配一片连续的字节存储单元并初始化DCW(DCWU):分配一片连续的半字存储单元并初始化DCD(DCDU):分配一片连续的字存储单元并
初始化DCDO:分配一片按字对齐的字内存单元并初始化DCI:分配一片字或半字对齐内存单元并初始化DCQ(DCQU):分配一片以8字节为单位的连续存储单元并初始化DCFS(DCFSU):为单精度浮点数分配一片连续字存储单元并初始化DCFD(DCFDU):为双精度浮点
数分配一片连续字存储单元并初始化SPACE:分配一片连续的存储单元FIELD:定义一个结构化的内存表的数据区MAP:定义一个结构化的内存表首地址LTORG:定义一个数据缓冲区池(literallypool)的开始page西安邮电学院计算机系282022/11/2
4使用示例:StrDCB“Thisisatest!‛;分配一片连续的字节存储单元并初始化。DataTestDCW1,2,3;分配一片连续的半字存储单元并初始化。DataTestDCD4,5,6;分配一片连续的字存储单元并初始化。page西
安邮电学院计算机系292022/11/24课堂练习:假设Str的地址为:8008,有如下伪操作,试画出内存中数据的分布示意图。page西安邮电学院计算机系302022/11/24page西安邮电学院计算机系312022/11/24内存中的数据分布图
page西安邮电学院计算机系322022/11/242.2ARM汇编程序中的数据定义数据定义的目的是为目标系统数学模型的各种抽象数据类型分配存储单元,同时进行初始化。①DCB、DCW和DCD汇编器伪指令stringDCB“
HelloWorld!”;分配一片连续的字节存储单元并初始化halfwordDCW1,2,3;分配一片连续的半字存储单元并初始化wordDCD1,2,3;分配一片连续的字存储单元并初始化②SPACE汇编器伪指令dat
aSPACE1024;分配一片连续的存储区域并初始化为0page西安邮电学院计算机系332022/11/24③LTORG汇编器伪指令LTORG用于声明一个文字池(literalpool),用于存放常量。
ARM汇编语言提供了LDR加载指令附加文字池的方法,文字池中可以存放任意的32比特数,LDR加载指令相对寻址文字池,以实现对任意立即数的访问。汇编过程中,汇编器会默认地在每一个段的末尾填加一个文字池。需要注意的是,文字池不能远离文字池使用者(LDR指令),因为LD
R指令的寻址范围是指令位置的前后4KB。如果用户程序比较大,则可能使程序段的末尾超出4KB范围,此时需要在程序中的适当位置,使用LTORG伪指令显式声明文字池。一般总可以在LDR伪指令前后4KB的范围内找到分支指令,文字池可声明在分支(B)指令之后的紧邻位置,不会影响代码的
正常执行,因为B指令总是会将程序的执行转移到其它地方的。page西安邮电学院计算机系342022/11/24I.缺省文字池AREAdefault,CODE,READONLYENTRYCODE32startLDRR1,=0xABCDEFLDRR2,=0x
101ADDR3,R1,R2Bstart;汇编器默认的文字池位置,常数0xABCDEF、0x101即存放于此ENDstart[0xe59f1008]ldrr1,0x00008010;=#0x00abcdef000080
04[0xe59f2008]ldrr2,0x00008014;=#0x0000010100008008[0xe0813002]addr3,r1,r20000800c[0xeafffffe]b0x800c;(start+0xc)00008010[0x00abcdef]dcd0x00abcd
ef....00008014[0x00000101]dcd0x00000101....page西安邮电学院计算机系352022/11/24II.自定义文字池AREAdefault,CODE,READONLYENTRYCODE32
startLDRR1,=0xABCDEFLDRR2,=0x101ADDR3,R1,R2Bbranch…;其它汇编代码branch…;其它汇编代码otherSPACE4096END汇编器在每一个程序段的末尾附加缺省文字池,如果程序段较长,这个缺省的文字
池和LDR指令的距离有可能超出了4KB,那么LDR指令也不能正确加载数据。AREAdefault,CODE,READONLYENTRYCODE32startLDRR1,=0xABCDEFLDRR2,=0
x101ADDR3,R1,R2BbranchLTORG…;其它汇编代码branch…;其它汇编代码otherSPACE4096ENDstart[0xe59f1008]ldrr1,0x00008010;=#0x00abcdef00008
004[0xe59f2008]ldrr2,0x00008014;=#0x0000010100008008[0xe0813002]addr3,r1,r20000800c[0xea000001]bbranch00008010[0x00abcdef]dcd0
x00abcdef....00008014[0x00000101]dcd0x00000101....branch[0xe1a01001]movr1,r10000801c[0xeafffff7]bstartother[0x00000000]dcd0x0
0000000....00008024[0x00000000]dcd0x00000000....00008028[0x00000000]dcd0x00000000....page西安邮电学院计算机系362022/11/24其它常用的伪操作AREAALIGNCODE16、CODE32ENT
RYENDEQUEXPORT(或GLOBAL)IMPORTEXTERNGET(或INCLUDE)INCBINRNROUTpage西安邮电学院计算机系372022/11/242.3汇编语言程序的上机过程汇编语言上机环境编辑程序编译程序连接汇编程序调试汇编
程序通过通过完成不通过,重新修改(语法错误)不通过,重新修改(逻辑错误)page西安邮电学院计算机系382022/11/242.3.1编辑汇编语言源程序1建立工程文件page西安邮电学院计算机系392022/11/242编辑源文件page西
安邮电学院计算机系402022/11/243添加源文件page西安邮电学院计算机系412022/11/242.3.2编译连接源程序在编译连接之前还需要通过DebugSettings对话框对项目的运行环境进行一些设置。这里采用默认设置。编译时可以通过Projectcom
pile对源文件进行编译,然后再连接。但是比较简便的做法是直接单击工程窗口的Make图标按钮。page西安邮电学院计算机系422022/11/24page西安邮电学院计算机系432022/11/242.3.3调试汇编程序page西安邮电学院计算机系44202
2/11/24page西安邮电学院计算机系452022/11/24第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程page西安邮电学院计算机系462022/11/243ARM汇编语言程序设
计程序设计步骤简单程序设计分支程序设计循环程序设计子程序设计page西安邮电学院计算机系472022/11/24程序设计步骤分析题目确定算法。合理分配存储空间和寄存器根据算法画出程序框图根据框图编写程序上机调
试程序page西安邮电学院计算机系482022/11/241.分析题目与确定算法算法:●解决实际问题的数学模型●相同的问题有不同的算法实现●不同的算法在运行速度,占据的空间不同2.合理分配存储空间和寄存器:●合理地为原始数据,中
间结果以及最终结果安排存储空间。●分配原则:够用就好,不浪费空间,不定义多余变量,变量名合乎常规,增强可读性。page西安邮电学院计算机系492022/11/243.画出程序的流程图矩形框:菱形框:分支判断椭圆框:程序的开始或结束圆框:流程图之间的
连接箭头:处理流程圆圈:连接流程图某个处理page西安邮电学院计算机系502022/11/244.根据流程图编制语句:●简洁明了,必要的注释●不要出现绝对地址●注意中英文字符,半/全角,各数制对齐等5.汇编
调试程序:●ADS进行汇编、连接;●AXD进行调试。6.判断程序质量的标准●程序执行的时间●程序所占用的内存字节数●程序的语句行数page西安邮电学院计算机系512022/11/241.结构化程序设计的基本概念迪杰斯克拉(E.W.dijkstra
)在1969年提出结构化程序设计的基本思想①采用“自顶向下,逐步求精”的程序设计方法。②“单入口单出口”的控制结构。“自顶向下、逐步求精‛程序设计方法的主导思想是从问题本身开始,对问题进行分解,将解决问题的方法步骤逐步细化,分解为由基本程序结构模块组成
的结构化程序框图;“单入口单出口‛的思想认为一个复杂的程序,如果它仅是由顺序、分支、循环和子程序四种基本程序结构的组合、嵌套构成,那么这个新构造的程序一定是一个单入口单出口的程序。page西安邮电学院计算
机系522022/11/242.汇编语言程序设计的流程使用计算机通过编程序解决某一问题时,通常按以下步骤进行:①分析问题,建立数学模型;②确定算法;③设计程序流程图;④合理分配寄存器、存储空间和外设资源;⑤编制程序;⑥调试程序;⑦形成文档;研讨目标系统的本质特性,用数
学方法对其本质特性进行抽象描述,建立目标系统的数学表示模型在已建立的目标系统数学表示模型上,进一步研讨目标系统的内在规则,设计相应处理法则方案(算法分析与描述)把解题的方法、步骤用框图形式表示。如果问题比较复杂,那么可以逐步细化,直到每一框图
可以容易编程为止。流程图不仅便于程序的编制,且对程序逻辑正确性也比较容易查找和修改。处理条件是否满足?结束开始YN转向1(1)处理框(2)判断框(3)起止框(4)连接框(5)流向框转向1①合理地分配存储器资源,将前述的目标系统‘数据结构模型’表示到各存储器单元。②C
PU寄存器数量有限,在程序中,大多数操作都要使用寄存器;并且有的操作使用特定的寄存器(如堆栈操作使用SP/R13等),程序中要合理分配各寄存器的用途。用计算机语言,对数据结构模型和流程图表示的算法进行准确地描述。
①语法调试:排除程序中的语法错误。②功能调试:保证程序的逻辑功能正确性。用文档形式记录说明程序的功能、使用方法、程序结构、算法流程等每一个阶段的工作。page西安邮电学院计算机系532022/11/243.顺序程序设计顺序程序
是一种最简单的程序结构,也称为直线程序,它的执行自始自终按照语句的先后顺序进行。这种结构的流程图,除了有一个起始框,一个终止框外,就是若干执行框。page西安邮电学院计算机系542022/11/24例4-2试编制一程序,完成10+3的操作。开始R0<=10R1<=3R0<=R0+R1结束AREAA
RMex,CODE,READONLY;代码段名ARMexENTRY;程序的入口CODE32startMOVR0,#10;将立即数10存入寄存器R0MOVR1,#3;将立即数3存入寄存器R1ADDR0,R0,R1;R0=R0+R1stopMOV
R0,#0x18;这三条指令是ADS调试环境特约LDRR1,=0x20026;程序运行结束返回编译器调试环境SWI0x123456END;结束page西安邮电学院计算机系552022/11/244.分支程序设计
许多实际问题需要根据不同的情况作出不同的处理。在程序中,把不同的处理方法编制成各自的处理程序段,运行时由机器根据不同的条件自动作出判断,选择执行相应的处理程序段。这样的程序结构中,计算机不再完全按指令存储的顺序执行,称之为分支。分支程序使用子程序调用指
令BL、转移指令B或带状态转移指令BX来实现。page西安邮电学院计算机系562022/11/24例4-3给定以下符号函数:000101xxxy任意给定值,假定为-25,存放在x单元,函数值存放在y单元;要求根据x中的值来确定y的值。开始R0Add
ress(x)R1Address(y)R2Value(x)R2比较0?R3=0ZEROR3=1PLUSR3=-1R2=0R2>0R2<0[R1]R3结束R3=-1R3=0AREAsymbol,CODE,READONLY;代码段的名字symbolENTRY
;程序的入口CODE32startLDRR0,=x;加载数据段中的变量x地址,存入R0LDRR1,=y;加载数据段中的变量y地址,存入R1LDRR2,[R0];加载变量x的值,存入R2compareCMPR2,#0;将R2的值与0作比较BEQZERO;如果R2等于0,那么转向标号ZERO
处BGTPLUS;如果R2大于0,那么转向标号PLUS处MOVR3,#-1;否则,R2小于0,将-1存入R3中BstopZEROMOVR3,#0;R2等于0,将0存入R3中BstopPLUSMOVR3,
#1;R2大于0,将1存入R3中;续上段代码stopSTRR3,[R1]MOVR0,#0x18LDRR1,=0x20026SWI0x123456AREAData,DATA,READWRITExDCD-25yDCD0ENDpage西安邮电学院计算机系572022/11/245.循环程序设计顺序程序
和分支程序中的指令每次运行最多只执行一次。在实际应用中重复地做某些事的情况是很多的,这也是计算机最擅长的工作方式。重复地执行某些指令,最好用循环程序来实现。循环程序的结构初始化循环体修改结束处理结束循环?YN(a)先执行后判断初始化循环体修改结束处理进入循环?YN(b)先判断后执行初始
化循环体修改判断判断结束循环程序的主要部分,视具体情况而定:可以是一个顺序程序、分支程序或另一个循环程序。计数控制循环:通过计数循环次数,判断是否已达到预定次数,控制循环。条件控制循环:通过判断循环终止条
件是否已成立,控制循环。建立循环初始值。如设置地址指针、计数器、其他循环参数的起始值等。判断循环结束条件是否成立,决定是否继续循环。对循环结束进行适当处理;有的循环程序可以没有这部分。为执行下一个循环而修改某些参数,尤其循环控制变量的修改等。page西安邮电学院计算机
系582022/11/24①用计数控制循环适用于已知循环次数的循环程序设计例4-4从x单元开始的30个连续字单元中存放有30个无符号数,从中找出最大者送入y单元中。分析:根据题意,把第一个数先送入Rx寄存器,将Rx中的数与后面的29个数逐个进行比较,如果Rx中的数较小
,则将该较大的数送入Rx;继续与余下的数据逐个比较。在比较过程中,Rx中始终保持较大的数,共计比较29次,则最终Rx中保留了最大数,最后把Rx中的数(最大者)送入y单元。开始R0Address(x)R1Address(y)R2=29,循环次数;R3[R0]R0=R0+
4R4[R0]R3<R4?R3R4R2=0?[y]R3结束compare转向1转向1R2=R2-1转向2转向3转向3转向2YYNNAREAmax,CODE,READONLY;代码段的名字maxENTRY;程序的入口CODE32numEQU29;比较的次数startLDRR0,=x;R0指向源数据块
xLDRR1,=y;R1指向单元yLDRR2,=num;R2作为计数器LDRR3,[R0];将源数据块x中第一个数加载到R3中compareADDR0,R0,#4;每进行一次比较,将R0指针地址加4LDRR4,[R0];依次将源数据块x中下一个数加载到R4中CMPR3,R4;比较R3和
R4中数的大小MOVCCR3,R4;如果R3小于R4,则将较大的数送入R3中SUBSR2,R2,#1;计数器值减1BNEcompare;如果不为0,那么继续跳到compare执行STREQR3,[R1];如果为0,那么循环比较结束,R3是最大
的数;并且将R3中的数加载到R1指向的单元(即y)中stopMOVr0,#0x18LDRr1,=0x20026SWI0x123456AREAData,DATA,READWRITExDCD73,59,61,34,81,107,22
5,231,54,43DCD100,35,1,42,222,254,34,71,100,31DCD33,119,13,44,18,147,55,244,97,3yDCD0ENDpage西安邮电学院计算机系592022/11/24②适用于无法确定循环次数,
但知道循环结束的条件的循环程序设计例4-5从自然数1开始累加,直到累加和大于1000为止,统计被累加的自然数的个数,并把统计的个数送入n单元,把累加和送入sum单元。分析:根据题意,被累加的自然数的个数事先未知,因此不能用计数方法控制循环。但题目中给定一个条件,即累加和
大于1000则停止累加,因此,可以根据这一条件控制循环。我们用R3寄存器放累加和,用R4寄存器放每次取得的自然数,其中它的值也是统计自然数的个数。开始R0Address(n)R1Address(sum)R3=0,R4=0R5=1000R4
=R4+1R3=R4+R3R3是自然数累加和R3<=1000?累加和不大于1000?[R1]R3[R0]R4结束转向1转向1转向2转向2continueYNAREASUM,CODE,READONLY;代码段的名字SUMENTRY;程序的入口CODE3
2startLDRR0,=n;将数据段中自然数的个数n的地址加载到R0寄存器LDRR1,=sum;将数据段中自然数的累加和sum的地址加载到R1寄存器LDRR3,=0;R3存放自然数的累加和LDRR4,=0;R4用于循环个数的统计/每次取
得的自然数LDRR5,=1000;R5用于循环结束的界限值continueADDR4,R4,#1;取下一个自然数ADDR3,R3,R4;累加自然数CMPR3,R5;比较累加和是否超过了1000BCCcontinue;如果小于1000,那么跳到compare
执行STRCSR3,[R1];如果大于1000,那么将累加和存储到R1所指向的单元中STRCSR4,[R0];如果大于1000,那么将已累加的自然数个数值存储;到R0所指向的单元中stopMOVr0,#0x18LDRr1,=0x20026SWI0x123456AREADat
a,DATA,READWRITEnDCD0;定义累加的自然数的个数sumDCD0;定义自然数的累加和ENDpage西安邮电学院计算机系602022/11/24例:编制程序使S=1+2×3+3×4+4×5+…+N(N+1),直到N等于10为止。分析过程算法功能:
相邻数相乘MUL累加ADD循环次数:10CMPB指令初始值S=1NN+1部分和N(N+1)寄存器分配R0:S1R0+R3得S值R1:N的初始值2循环变量R2:N+1由R1=1求得R3:N(N+1)流程图page西
安邮电学院计算机系612022/11/24源程序:AREAEX4_45,CODE,READONLYENTRYCODE32STARTMOVR0,#1;R0用作累加,置初值1,SMOVR1,#2;R1用作第一个乘数,初值为2,NREPEATADDR2,R1,#
1;R2用作第二个乘数,N+1MULR3,R2,R1;实现N*(N+1)部分积存于R3ADDR0,R0,R3;将部分积累加至R0ADDR1,R1,#1;修改N的值得到下一轮乘数CMPR1,#10;循环次数比较BLEREPEAT;未完成则重复ENDpage西安邮电学
院计算机系622022/11/24多重循环程序设计多重循环即循环体内套有循环。设计多重循环程序时,可以从外层循环到内层循环一层一层地进行。通常在设计外层循环时,仅把内层循环看成一个处理粗框,然后再将该粗框细化,分成置初值、工作、修改和控制四个组成部分。当
内层循环设计完之后,用其替换外层循环体中被视为一个处理粗框的对应部分,这样就构成了一个多重循环。page西安邮电学院计算机系632022/11/24多重循环程序设计多重循环又称循环嵌套,即循环套循环。有些问题比较复杂,单重
循环难以解决,必须使用多重循环。在使用多重循环时,必须注意以下几点:⑴关系:内循环必须完整地包含在外循环内,内外循环不能相互交叉。⑵跳转:内循环既可以嵌套在外循环中,也可以几个内循环并列存在。可以从内循环中直接跳到外循环,但不能从外循环直接跳进内循环中。⑶注意:防止出现“死循环”。无论是外循环,还
是内循环,千万不要使循环返回到初始部分,这一点应当特别注意。⑷参数设置:每次通过外循环再次进入内循环时,初始条件必须重新设置。page西安邮电学院计算机系642022/11/24⑷每次通过外循环再次进入内循环时,初始条件必须重新设置。[例]利用
逐次求大数的方法对内存单元ARRAY开始的一字节为单位的无符号数进行从大到小排序。根据题意,排序方法为:4938651297135527788549496565979738384949656578788585786555493827131212ARRAYR6BXSISISISISISI
SISISIBXSISISISISISISISIpage西安邮电学院计算机系652022/11/24综合举例:在以BUF为首址的字存储区中存放有10个无符号数0x0FF,0x00,0x40,0x10,0x90,0x20,0x80,0x30,0x50
,0x70,0x60,现需将它们按从小到大的顺序排列在BUF存储区中,试编写其程序。1、分析2、流程3、编程4、调测page西安邮电学院计算机系662022/11/24R1R2流程图分析:采用逐一比较法:将第一个
存储单元中的数与其后n-1个存储单元中的数逐一比较,每次比较之后,总是把小者放在第一个存储单元之中,经过n-1次比较之后,n个数中最小者存入第一存储单元中;接着从第二个存储单元开始,同理,经过n-2次比较之后,
得到n-1个数中最小者存入第二存储单元中;如此类推,当最后两个存储单元的数比较完成之后,从小到大的排列顺序就实现了。“冒泡排序”算法。page西安邮电学院计算机系672022/11/24各寄存器分配功能如下:R0:用来指示缓冲区初始地址R1:外循
环计数器R2:内循环计数器R3:外循环地址指针R4:内循环地指针R5:内循环下一个数地址指针R6:存放内循环一轮比较的最小值R7:存放内循环取出的下一个比较值page西安邮电学院计算机系682022/11/2
4源程序如下:NEQU10AREAEX4_47,CODE,READONLYENTRYCODE32STARTLDRR0,=BUF;指向数组的首地址MOVR1,#0;外循环计数器MOVR2,#0;内循环计数器LOOPIADDR3,R0,R1,
LSL#2;外循环首地址存R3MOVR4,R3;内循环首地址存R4ADDR2,R1,#1;内循环计数器初值MOVR5,R4;内循环下一地址初值LDRR6,[R4];取内循环下一地址值R4page西安邮电学院计算机系692022/11/24LOOPJADDR5,R5,#4;内循
环下一地址值LDRR7,[R5];取出下一地址值至R7CMPR6,R7;比较BLTNEXT;小则取下一个SWPR7,R6,[R5];大则交换,最小值R6MOVR6,R7NEXTADDR2,R2,#1;内循环计数CMPR2,#N;循环中止条件BLTL
OOPJ;小于N则继续内循环SWPR7,R6,[R3];否则,内循环一轮结束;将最小数存入外循环的首地址处ADDR1,R1,#1;外循环计数page西安邮电学院计算机系702022/11/24CMPR1,#N-1;外循环中止
条件BLTLOOPI;小于N-1则继续执行外循环BSTARTAREABlockData,DATA,READWRITEBUFDCD0x0FF,0x00,0x40,0x10,0x90,0x20,0x80,0x30,0x50,0x70END采用冒泡排序方法,程序运行的结果如下:00H,10
H,20H,30H,40H,50H,70H,80H,90H,FFHpage西安邮电学院计算机系712022/11/24程序模块化结构STARTLOOPILOOPJBLTNEXTNEXTBLTLOOPJBLTLOOPIBSTARTpage西安邮电学院计算机系722
022/11/24page西安邮电学院计算机系732022/11/246.子程序设计子程序概念如果在一个程序中的多处用到同一段程序代码,那么可以把这段共同的程序代码抽取出来,写成一个相对独立的程序段,每当需要执行这段代码时,就调用这个程序段,执行完这个程序段后,再返回原来调用它的程序。这
样编写程序时,就不必重复写这段代码了,而这样的程序段称为子程序或子过程。子程序的调用与返回主程序中使用BL指令实现子程序的调用BL子程序名在子程序结束处,使用如下指令返回到主程序中。MOVPC,LR主程序与子程序之间的参数传递主程序调用子程序时,可以向子程
序传递一些参数;同样,子程序运行后也可把一些结果参数传回给主程序。主程序与子程序之间的这种信息传递称为参数传递。三种参数传递方式①寄存器传递参数方式②存储区域传递参数方式③堆栈传递参数方式page西安邮电学院计算机系742022
/11/24①寄存器传递参数方式技术思想:主程序将待传递的数据直接写入约定的通用寄存器,再进行BL子程序调用;或子程序返回后,主程序直接从约定的通用寄存器中获得子程序的结果数据。应用特点:这种方式适合
于传递较少参数的应用场合。例4-5用子程序实现内存区里的字符串拷贝功能,即将存储单元中源字符串对应拷贝到目的字符串中。解题思路:通过设定两个地址指针,分别指向存储区中的源字符串和目的字符串;然后通过加载和存储指令(LDR和STR)的寄存器间接寻址方式,依次从
源字符串读取一个字符数据,写入到目的字符串的对应字符位置中,直到遇到源字符串的结束标志’0’为止。AREAStrCopy,CODE,READONLYENTRYCODE32startLDRR1,=srcstr;R1指向数据区的源字符串LDRR0,=dststr;R0指向数据区的目的字
符串BLstrcopy;调用子程序strcopy,完成字符串拷贝stopMOVR0,#0x18;程序结束返回编译器调试环境LDRR1,=0x20026SWI0x123456strcopyLDRBR2,[r1],#1;将R1指向的单元内容加载到R2中STRBR2,[r0],#1;将R
2中的数存储到R0指向的单元中CMPR2,#0;检查R0的值是否等于0BNEstrcopy;如果不等于0,那么转到strcopy处执行MOVPC,LR;子程序返回AREAStrings,DATA,READ
WRITEsrcstrDCB"Firststring-source",0;源字符串dststrDCB"Secondstring-destination",0;目的字符串ENDpage西安邮电学院计算机系752
022/11/24②存储区域传递参数方式技术思想:主程序和子程序约定了某一共享内存块用于参数传递,主程序在BL调用子程序前,先将要传递的参数写入到约定的存储单元,子程序可从约定的内存读取这些参数;子程序返回时,也
可以使用该方式将数据传给主程序。应用特点:这种方式可以传递大批量数据。实现方法:当主程序与子程序有较多的数据需要传递时,可以通过共享内存区或传内存数据块地址方式来传递批量数据。①通过伪指令ADR直接装载近距离数据块地址;②通过伪指令
ADRL直接装载较近距离数据块地址;③通过语句LDRRd,=Label转载远距离的数据块地址;例4-6通过设置的入口参数查找函数地址表,实现选择不同的函数功能。说明:本题中通过事先将函数地址存放在存储单元中,通过
查找地址表的方法,实现根据“选择项(choice)”进入不同的函数体功能。AREAJump,CODE,READONLYnumEQU4;函数地址表内容的个数ENTRYCODE32startLDRR0,=choice;R0指向存储区的choice
单元LDRR0,[R0];设置第一个参数:选择执行哪一个函数MOVR1,#16;设置第1个操作数MOVR2,#2;设置第2个操作数BLarithfunc;调用子程序arithfuncstopMOVR0,#0x18;程序结束返回编译器调试环境LDRR1,=0x20026SWI0x1234
56arithfuncCMPR0,#num;比较R0的值是否超过函数地址表的个数MOVHSpc,lr;如果大于,那么就返回到标号stop处ADRR3,JumpTable;将函数地址表的地址作为基地址LDRpc,[R3,R0,LSL#2];根据R0参数进入对应的子程序Jump
Table;函数地址表的入口基地址DCDDoAdd;加法子程序DCDDoSub;减法子程序DCDDoMul;乘法子程序DCDDoDiv;除法子程序DoAddADDR0,R1,R2;R0=R1+R2MOVPC,LR;返回DoSubSUBR0,R1,R2;R0=R1-R2MOVPC,LR;
返回DoMulMOVR0,R1,LSLR2;R0=R1<<R2MOVPC,LR;返回DoDivMOVR0,R1,LSRR2;R0=R1>>R2MOVPC,LR;返回AREANUM,DATA,READWR
ITEchoiceDCD3;0:表示选择加法子程序1:表示选择减法子程序;2:表示选择乘法子程序3:表示选择除法子程序ENDpage西安邮电学院计算机系762022/11/24③堆栈传递参数方式主程
序和子程序使用同一个堆栈,主程序在BL调用子程序前,先将要传递的参数压入到堆栈中,子程序可从堆栈中读取传过来的数据;子程序返回需要向主程序传递参数时,也可使用此方法。page西安邮电学院计算机系772022/11/24第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编
语言程序设计的基本方法4.汇编语言和C语言交叉编程page西安邮电学院计算机系782022/11/241.汇编程序与C程序间变量互访②C程序访问汇编程序中的变量具体操作步骤:在汇编语言程序中,用伪指令“global”定义全局变量,变量名必须是下划线“_”为首字符
的字母数字串;C程序中将该变量声明为外部变量,即可访问汇编程序定义的全局变量。①汇编程序访问C程序中的变量具体操作步骤:在C程序中,将供汇编程序访问的变量用关键字extern声明为全局变量;汇编程序中,用伪指令IMPORT引入C程
序中的全局变量;使用伪指令LDR读取这个全局变量的地址;使用指令LDR读取这个全局变量的值;在汇编程序中使用这个全局变量;例:汇编程序和C程序间变量互访/*print.c定义全局变量,并作为主程序*/#include<stdio.h>externintg_
var=124;/*全局变量*/externasmVisit(void);/*汇编程序中声明的全局函数*/externint_multiple;/*声明汇编程序中的全局变量_multiple为外部变量*/intmain(
){printf("Originalvalueofg_varis:%d\n",g_var);asmVisit();/*调用汇编程序中的函数,访问全局变量g_var*/printf("multis%d",_multiple);/*访问汇编程序中全局变量_multiple
*/printf("Modifiedvalueofg_varis:%d",g_var);return0;};visit.s文件AREAasmfile,CODE,READONLYEXPORTasmVisit;声明全局函数,供C程序调用IMPORTg_v
ar;引入在C程序中声明定义的全局变量GLOBAL_multiple;声明全局变量,供C程序访问asmVisitLDRR0,=g_varLDRR1,[R0]LDRR2,=_multipleLDRR2,[R2]MOVR3,R1,LSLR2;将R1中的值扩大指定的倍数STRR3,[R
0]MOVPC,LRAREAasmData,DATA,READWRITE_multipleDCD2ENDpage西安邮电学院计算机系792022/11/242.汇编程序调用C程序汇编程序中调用C函数,只需在汇编
程序中用伪指令IMPORT将需要调用的C函数名引用即可,然后将C函数放在一个独立的C文件中进行编译,剩下的工作就由链接器来处理。汇编程序与C函数间参数的传递规则遵守ATPCS(ARMThumbProcedureCal
lStandard)规则:用ARM处理器寄存器组中的{R0-R3}作为参数传递和结果返回寄存器;如果参数数目超过4个,则使用堆栈进行传递。;asmfile.s文件AREAasmfile,CODE,READONLYIMPOR
TcFun;声明引用外部函数ENTRYCODE32startMOVR0,#1MOVR1,#2MOVR2,#3BLcFun;此时结果和在R0中stopMOVR0,#0x18;程序结束返回编译器调试环境LDRR1,=0x20
026SWI0x123456END/*cFun.c文件,由asmFile.s文件调用*/intcFun(inta,intb,intc){returna+b+c;}page西安邮电学院计算机系802022/11/243.C程序调用汇编程序C程序调用汇编程序子程序,要做的主要
工作有两个:一是在C程序中用关键字extern声明汇编子程序的函数原型(C程序是函数结构的程序设计风格),声明该函数的实现代码在其他文件中;二是在汇编程序中用伪指令EXPORT导出子程序名,并且用该子程序名作为汇编代码段的标识,
最后用movpc,lr返回。这样,在C程序中就可以像调用C函数一样调用该汇编子程序了。具体操作步骤:汇编程序中,用该子程序名作为汇编代码段的标识,定义程序代码,最后用“MOVPC,LR”指令返回;汇编程序
中用伪指令EXPORT导出子程序名;C程序中用关键字extern声明该汇编子程序的函数原型;然后就可在C程序中访问该函数;函数调用时的参数传递规则:寄存器组中的{R0-R3}作为参数传递而返回值用寄存
器R0返回;如果参数数目超过4个,则使用堆栈进行传递。/*cfile.c*/#include<stdio.h>externvoidstrcpy(constchar*src,char*dest);intmain(){char*s="thisstringisinCfile";char
temp[32];strcpy(s,temp);printf("Sourcestring:%s\n",s);printf("Destinationsting:%s",temp);return0;};asmfile.sAREAstrcpy,CODE,READONLYEXPORTstrcpy
;完成源字符串R0到目的字符串R1的拷贝loopLDRBR5,[R0],#1CMPR5,#0;是否到字符串结束BEQexitSTRBR5,[R1],#1BloopexitMOVPC,LRENDpage西安邮电学院计算机系812022/11/244.C程序中内嵌汇编代码C程序中内嵌的汇
编代码可使用大部分的ARM和Thumb指令,存在一些限制,主要有下面几个方面:不能直接向寄存器PC赋值,程序跳转要使用指令B或者BL;在访问物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;R12和R13常被编译器用来存放中间编译结
果,计算表达式值时可能将R0~R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器;一般不要直接指定物理寄存器,而让编译器进行分配;内嵌汇编代码中定义的变量不能在C函数体中访问,但内嵌汇编代码可以通过指针的方式访问C函数体中定义的变量。在C程序中
使用‚__asm”关键字标记内嵌汇编代码,格式如下:__asm;注意是双下划线{......;汇编指令编写的代码}#include<stdio.h>voidstrcpy(constchar*src,char*dest){charch;;检
查字符串是否结束的标志__asm{;功能:完成将源字符串src中的数据拷贝到目的字符串dest中LOOP:LDRBch,[src],#1STRBch,[dest],#1CMPch,#0BNELOOP}}intmain(){char*s="thisisaexampleAsmInC!";c
hartemp[64];strcpy(s,temp);printf("Originalstring:%s\n",s);printf("Copyedstring:%s",temp);return0;}