chapter4ARM7TDMI汇编语言程序设计_第1页
chapter4ARM7TDMI汇编语言程序设计_第2页
chapter4ARM7TDMI汇编语言程序设计_第3页
chapter4ARM7TDMI汇编语言程序设计_第4页
chapter4ARM7TDMI汇编语言程序设计_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

会计学1chapter4ARM7TDMI汇编语言程序设计22023/1/17第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程第1页/共64页32023/1/17第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程第2页/共64页42023/1/174.1汇编语言的基本概念语言

信息的传播载体。计算机语言

计算机可以识别、理解的语言。计算机语言的用途:

描述操作和数据。数据用于描述问题模型;操作用于描述问题处理方法和步骤;第3页/共64页52023/1/174.1汇编语言的基本概念

程序设计语言是专门为计算机编程所配置的语言。它们按照形式与功能的不同可分为三类,即机器语言、汇编语言和高级语言。1.机器语言机器语言(MachineLanguage)是由0和1二进制代码表示和存储的指令与数据。它的特点是能被机器直接识别与执行;程序所占内存空间较少。其缺点是难认、难记、难编、易错。第4页/共64页62023/1/172.汇编语言汇编语言(AssemblyLanguage)是一种面向物理层操作的计算机语言,是一种采用助记符表示指令的程序设计语言;汇编语言中使用助记符来表示指令的操作码和操作数,用标号或符号代表地址、常量或变量。

从机器角度看:汇编语言是一种面向物理层操作的计算机语言。不同的处理器类型,具有不同的汇编语言。使用汇编语言编写程序能够直接利用硬件系统的特性(如寄存器、标志、中断系统等),可直接对位、字节、字寄存器或存储单元、I/O端口进行处理,同时也能直接使用CPU指令系统提供的各种寻址方式,编制出高质量的程序,这样的程序不但占用内存空间少,而且执行速度快。第5页/共64页72023/1/172.汇编语言源程序示例AREAInit,CODE,READONLYENTRYStartLDRR0,=0x40000500MOVR1,#0x55STRR1,[R0]LDRR0,=0x40000504MOVR1,#0xAASTRR1,[R0]…END第6页/共64页82023/1/172.汇编语言上机过程设计、编辑汇编语言源程序;汇编、连接、下载到目标系统;调试运行;第7页/共64页92023/1/173.高级语言高级语言(HighLevelLanguage)是脱离具体机器(即独立于机器)的通用语言,不依赖于特定计算机的结构与指令系统。第8页/共64页102023/1/17第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程第9页/共64页112023/1/174.2ARM汇编程序的组成与结构;文件名:TEST1.S

;功能:实现字符串拷贝功能

;说明:使用ARMulate软件仿真调试

AREA Example1,CODE,READONLY;声明代码段Example1

numEQU20 ;设置拷贝字的个数

ENTRY ;标识程序入口

CODE32 ;声明32位ARM指令START LDR R0,=src;R0指向源数据块

LDR R1,=dst;R1指向目的数据块

MOV R2,#num;R2需要拷贝的数据个数

wordcopy

LDR

R3,[R0],#4

;从源数据块中取一个字,放入R3中,

;R0=R0+4

STR

R3,[R1],#4

;将R3中的数据存入R1指向的存储

;单元中,R1=R1+4

SUBS

R2,R2,#1

;R2计数器减1

BNE

wordcopy

;如果R2不为0,则转向wordcopy处使用“;”进行注释标号顶格写程序代码段第10页/共64页122023/1/17stop MOV R0,#0x18 ;程序运行结束返回编译器调试环境

LDR R1,=0x20026 SWI 0x123456

AREABlockData,DATA,READWRITE

;数据段的名字BlockDataSrc DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4Dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 AREA|.extra|,NOINIT,READWRITE

;未初始数据段的名字.extradata SPACE 1024 END ;文件结束

声明文件结束第11页/共64页132023/1/174.2ARM汇编程序的组成与结构段:ARM汇编程序由段组成(程序段、数据段);段是由汇编器伪指令AREA定义的相对独立程序块;段的属性:READONLY(只读)或READWRITE(读写)分别用于定义一个代码段或数据段;第12页/共64页142023/1/174.2ARM汇编程序的组成与结构标识符(标号):(用途)用来表示指令的地址、数据的地址、变量、过程名和常量;(组成)标号是一个自行设计的字母数字串,通常以字母开头,由字母、数字、下划线等组成;(注意1)标号不能与寄存器名、指令助记符、伪指令(操作)助记符等“关键字”同名;(注意2)标号必须在一行的开头书写,不能留空格;第13页/共64页152023/1/174.2.1汇编器伪指令ARM汇编语言程序中,有一些特殊的指令助记符,称为汇编器伪指令。它们无论表示形式或其在程序中所处的位置,都与指令相似,但二者之间有着重要的区别。指令是供CPU执行的操作命令,每条指令对应CPU的一种特定操作,在用户代码运行期间执行;而汇编器伪指令是供汇编器处理的命令,在汇编过程中由汇编器进行处理,例如定义数据、分配存储区、定义段、定义宏等;汇编以后,汇编器伪指令不产生与之对应的目标代码。第14页/共64页162023/1/174.2.1汇编器伪指令AREACODE16、CODE32ENTRYENDEQUDCB、DCW、DCDSPACELTORGALIGN第15页/共64页172023/1/174.2.1汇编器伪指令

AREA用途:段声明;格式:AREA<段名>,<段属性>,<读写属性>其中:段名

用户定义的标识符;段属性CODE/DATA读写属性READONLY/READWRITE第16页/共64页182023/1/17;文件名:TEST1.S

;功能:实现字符串拷贝功能

;说明:使用ARMulate软件仿真调试

AREA Example1,CODE,READONLY

;声明代码段Example1

numEQU20 ;设置拷贝字的个数

ENTRY ;标识程序入口

CODE32 ;声明32位ARM指令START LDR R0,=src;R0指向源数据块

LDR R1,=dst;R1指向目的数据块

MOV R2,#num;R2需要拷贝的数据个数

wordcopy

LDR

R3,[R0],#4

;从源数据块中取一个字,放入R3中,

;R0=R0+4

STR

R3,[R1],#4

;将R3中的数据存入R1指向的存储

;单元中,R1=R1+4

SUBS

R2,R2,#1

;R2计数器减1

BNE

wordcopy

;如果R2不为0,则转向wordcopy处第17页/共64页192023/1/17stop MOV R0,#0x18 ;程序运行结束返回编译器调试环境

LDR R1,=0x20026 SWI 0x123456

AREABlockData,DATA,READWRITE

;数据段的名字BlockDataSrc DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4Dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 AREA|.extra|,NOINIT,READWRITE

;未初始数据段的名字.extradata SPACE 1024 END ;文件结束

第18页/共64页202023/1/174.2.1汇编器伪指令

CODE16/32用途:声明后续行是16位的Thumb或是32位的ARM指令;格式:CODE16(CODE32)代码示例:

code16addr0,r1;Thumb指令

code32addr0,r1;ARM指令第19页/共64页212023/1/17;文件名:TEST1.S

;功能:实现字符串拷贝功能

;说明:使用ARMulate软件仿真调试

AREA Example1,CODE,READONLY;声明代码段Example1

numEQU20 ;设置拷贝字的个数

ENTRY ;标识程序入口

CODE32

;声明32位ARM指令START LDR R0,=src;R0指向源数据块

LDR R1,=dst;R1指向目的数据块

MOV R2,#num;R2需要拷贝的数据个数

wordcopy

LDR

R3,[R0],#4

;从源数据块中取一个字,放入R3中,

;R0=R0+4

STR

R3,[R1],#4

;将R3中的数据存入R1指向的存储

;单元中,R1=R1+4

SUBS

R2,R2,#1

;R2计数器减1

BNE

wordcopy

;如果R2不为0,则转向wordcopy处第20页/共64页222023/1/174.2.1汇编器伪指令

ENTRY用途:声明程序的入口,编译程序会把这个入口的地址定义为系统复位后的程序的起始点;格式:ENTRY代码示例:

AREAInit,CODE,READONLY

ENTRYCODE32StartLDRR0,=0x40000500LDRR1,#0xFFSTRR1,[R0]

…END第21页/共64页232023/1/174.2.1汇编器伪指令

END用途:声明汇编源程序的结束(末行);格式:END代码示例:

AREAInit,CODE,READONLYENTRY CODE32StartLDRR0,=0x3FF5000LDRR1,#0xFFSTRR1,[R0]

END第22页/共64页242023/1/174.2.1汇编器伪指令

EQU用途:声明程序的入口;格式:EQU代码示例:

AREAInit,CODE,READONLYZQL_V

EQU0x40000500ENTRY CODE32StartLDRR0,=ZQL_VLDRR1,#0xFFSTRR1,[R0]

…END第23页/共64页252023/1/174.2.1汇编器伪指令

DCB用途:在程序存储区预存字节数据;格式:<标号>DCB<字节数据列表>代码示例:

AREAInit,CODE,READONLYZQL_DB

DCB0x01,0x04,0x09,0x10,0x19ENTRY CODE32StartLDRR0,=ZQL_DB

LDRR2,[R0,R1]

…END备注:DCB也可用“=”代替;第24页/共64页262023/1/174.2.1汇编器伪指令

DCW用途:在程序存储区预存半字数据(2B);格式:<标号>DCW<半字数据列表>代码示例:

AREAInit,CODE,READONLYZQL_DW

DCW0x01,0x04,0x09,0x10,0x19ENTRY CODE32StartLDRR0,=ZQL_DW

LDRR2,[R0,R1,LSL#1]

…END备注:DCW预存的数据在存储器中半字对齐存放;第25页/共64页272023/1/174.2.1汇编器伪指令

DCD用途:在程序存储区预存字数据(4B);格式:<标号>DCD<字数据列表>代码示例:

AREAInit,CODE,READONLYZQL_DD

DCD0x01,0x04,0x09,0x10,0x19ENTRY CODE32StartLDRR0,=ZQL_DD

LDRR2,[R0,R1,LSL#2]

…END备注:DCD预存的数据在存储器中字对齐存放;

DCD也可用“&”代替;第26页/共64页282023/1/174.2.1汇编器伪指令

SPACE用途:在存储区预留初值为0x00的空间;格式:<标号>SPACE<字节个数>代码示例:

AREAInit,CODE,READONLYZQL_DDDCD0x01,0x04,0x09,0x10,0x19ENTRY CODE32StartLDRR0,=ZQL_DDLDRR2,[R0,R1,LSL#2]

…BuffSPACE4096END第27页/共64页292023/1/174.2.1汇编器伪指令

LTORG用途:声明一个文字池的位置;格式:LTORG文字池的起源与应用:用于预存放任何32bit的数据常量,供LDR加载指令使用,实现对任意立即数的访问;解释:立即数包含在32bit的指令码中,必须是‘8位图立即数’,这就限制了立即数的取值;ARM汇编语言提供了LDR加载指令附加文字池的方法,文字池中可以存放任意的32bit数,LDR加载指令相对寻址文字池,以实现对任意立即数的访问。第28页/共64页302023/1/17汇编过程中,汇编器会默认地在每一个程序段的末尾填加一个文字池。需要注意的是,文字池不能远离文字池使用者(LDR指令),因为LDR指令的寻址范围是指令位置的前后4KB。如果用户程序比较大,则可能使程序段的末尾超出4KB范围,此时需要在程序中的适当位置,使用LTORG伪指令显式声明文字池。一般总可以在LDR伪指令前后4KB的范围内找到分支指令,文字池可声明在分支(B)指令之后的紧邻位置,不会影响代码的正常执行,因为B指令总是会将程序的执行转移到其它地方的。第29页/共64页312023/1/17缺省文字池 AREAdefault,CODE,READONLY ENTRY CODE32start LDR R1, =0xABCDEF LDR R2, =0x101 ADD R3, R1, R2 B ·

;汇编器默认的文字池位置 ;常数0xABCDEF、0x101即存放于此 END地址机器指令码汇编指令注释start [0xe59f1008] ldr r1,0x00008010 ;=#0x00abcdef00008004 [0xe59f2008] ldr r2,0x00008014 ;=#0x0000010100008008 [0xe0813002] add r3,r1,r20000800c [0xeafffffe] b 0x800c ; (start+0xc)00008010 [0x00abcdef] dcd 0x00abcdef

00008014 [0x00000101] dcd 0x00000101

第30页/共64页322023/1/17自定义文字池 AREAdefault,CODE,READONLY ENTRY CODE32start

LDR R1, =0xABCDEF;文字池使用处 LDR R2, =0x101 ADD R3,R1, R2 Bbranch … ;其它汇编代码branch … ;其它汇编代码other SPACE4096 END;默认文字池位置超远!?汇编器缺省文字池位于程序段的末尾,如果程序段较长,这个缺省的文字池和LDR指令的距离有可能超出了4KB,那么LDR指令不能正确加载数据。 AREAdefault,CODE,READONLY ENTRY CODE32start

LDR R1, =0xABCDEF;文字池使用者 LDRR2, =0x101 ADDR3,R1,R2 Bbranch

LTORG ;显示声明文字池位置 … ;其它汇编代码branch … ;其它汇编代码other SPACE4096 ENDstart [0xe59f1008] ldr r1,0x00008010 ;=#0x00abcdef00008004 [0xe59f2008] ldr r2,0x00008014 ;=#0x0000010100008008 [0xe0813002] add r3,r1,r20000800c [0xea000001] b branch00008010 [0x00abcdef] dcd 0x00abcdef

00008014 [0x00000101] dcd 0x00000101

branch [0xe1a01001] mov r1,r10000801c [0xeafffff7] b startother [0x00000000] dcd 0x0000000000008024 [0x00000000] dcd 0x0000000000008028 [0x00000000] dcd 0x00000000第31页/共64页332023/1/174.2.1汇编器伪指令

LTORG用途:声明一个文字池(literalpool)的位置;格式:LTORG代码示例:

AREAEXP_LTOGR,CODE,READONLYENTRYCODE32StartLDRR0,=0x12345678LDRR2,=0x87654321

…Blabel

LTORG

…BuffSPACE4096END在文字池使用者±4KB范围内的某个B指令后临,使用LTORG声明文字池;第32页/共64页342023/1/17第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程第33页/共64页352023/1/174.3汇编语言程序设计的基本方法描述问题模型;(数据描述)(物理问题→数学抽象模型→计算机存储模型)描述问题处理方法;(算法描述)计算机语言主要用于编程(程序设计)。汇编语言程序设计的主要工作基于计算机工作平台,使用汇编语言:第34页/共64页362023/1/174.3汇编语言程序设计的基本方法计算机工作平台的知识;汇编指令系统基本掌握;数学建模、存储器表示基础知识;分析、解决问题方法描述能力;汇编语言程序设计的基本素质要求:第35页/共64页372023/1/174.3.1结构化程序设计的基本概念迪杰斯克拉(E.W.dijkstra)在1969年提出结构化程序设计的基本思想;采用“自顶向下,逐步求精”的程序设计方法。“单入口单出口”的控制结构。“自顶向下、逐步求精”程序设计方法的主导思想是从问题本身开始,对问题逐步分解,将解决问题的方法步骤逐步细化,分解为由基本程序结构模块组成的结构化程序框图,直至便于编程实现;“单入口单出口”的思想认为一个复杂的程序,如果它仅是由顺序、分支、循环和子程序四种基本程序结构的组合、嵌套构成,那么这个新构造的程序一定是一个单入口单出口的程序。

第36页/共64页382023/1/174.3.2汇编语言程序设计的流程使用计算机通过编程序解决某一问题时,通常按以下步骤进行:分析问题,建立数学模型;确定算法;设计程序流程图;合理分配寄存器、存储空间和外设资源;编制程序;调试程序;形成文档;研讨目标系统的本质特性,用数学方法对其本质特性进行抽象描述,建立目标系统的数学表示模型

在已建立的目标系统数学表示模型上,进一步研讨目标系统的内在规则,设计相应处理法则方案(算法分析与描述)把解题的方法、步骤用框图形式表示。如果问题比较复杂,那么可以逐步细化,直到每一框图可以容易编程为止。流程图不仅便于程序的编制,且对程序逻辑正确性也比较容易查找和修改。①合理地分配存储器资源,将前述的目标系统‘数据结构模型’表示到各存储器单元。②

CPU寄存器数量有限,在程序中,大多数操作都要使用寄存器;并且有的操作使用特定的寄存器(如堆栈操作使用SP/R13等),程序中要合理分配各寄存器的用途。用计算机语言,对数据结构模型和流程图表示的算法进行准确地描述。①语法调试:排除程序中的语法错误。②功能调试:保证程序的逻辑功能正确性。用文档形式记录说明程序的功能、使用方法、程序结构、算法流程等每一个阶段的工作。第37页/共64页392023/1/174.3.3顺序程序设计顺序程序是一种最简单的程序结构,也称为直线程序,它的执行自始自终按照语句的先后顺序进行。这种结构的流程图,除了有一个起始框,一个终止框外,就是若干执行框。第38页/共64页402023/1/17例4‑2试编制一程序,完成10+3的操作。

AREAARMex,CODE,READONLY ;代码段名ARMex ENTRY ;程序的入口

CODE32start

MOV R0, #10

;将立即数10存入寄存器R0

MOV R1, #3

;将立即数3存入寄存器R1

ADD R0, R0, R1

;R0=R0+R1stop MOV R0, #0x18 ;这三条指令是ADS调试环境特约

LDR R1, =0x20026 ;程序运行结束返回编译器调试环境

SWI 0x123456 END ;结束

第39页/共64页412023/1/174.3.4分支程序设计许多实际问题需要根据不同的情况作出不同的处理。在程序中,针对不同的情况把不同的处理方法编制成各自的处理程序段,运行时由机器根据当时的条件自动作出判断,选择执行相应的处理程序段。这样的程序结构中,计算机不再完全按指令存储的顺序执行,称之为分支。分支程序使用转移指令B、子程序调用指令BL或带状态转移指令BX来实现。第40页/共64页422023/1/17例4‑3给定以下符号函数:

任意给定值,假定为-25,存放在x单元,函数值存放在y单元;要求根据x中的值来确定y的值。

R3=-1R3=0 AREAsymbol,CODE,READONLY ;代码段的名字symbol ENTRY ;程序的入口

CODE32start LDRR0,=x ;加载数据段中的变量x地址,存入R0 LDRR1,=y ;加载数据段中的变量y地址,存入R1 LDR R2,[R0] ;加载变量x的值,存入R2compare CMP R2,#0 ;将R2的值与0作比较

BEQ ZERO ;如果R2等于0,那么转向标号ZERO处

BGT PLUS ;如果R2大于0,那么转向标号PLUS处

MOV R3,#-1 ;否则,R2小于0,将-1存入R3中

B stopZERO MOV R3,#0 ;R2等于0,将0存入R3中

B stopPLUS MOV R3,#1 ;R2大于0,将1存入R3中;续上段代码stop STR R3,[R1]

MOV R0,#0x18 LDR R1,=0x20026 SWI 0x123456

AREAData,DATA,READWRITEx DCD -25y DCD 0 END第41页/共64页432023/1/174.3.5循环程序设计顺序程序和分支程序中的指令每次运行最多只执行一次。在实际应用中重复地做某些事的情况很多,这也是计算机最擅长的工作方式。重复地执行某些指令,最好用循环程序来实现。循环程序的结构重复地执行同一种运算,直到某种条件满足。初始化循环体修改判断判断结束循环程序的主体业务代码,可以是一个顺序程序、分支程序或另一个循环程序。例如:计数控制循环;通过计数循环次数,判断是否已达到预定次数,控制循环。条件控制循环:通过判断循环终止条件是否已成立,控制循环。建立循环初始值。如设置地址指针、计数器、其他循环参数的起始值等。判断循环结束条件是否成立,决定是否继续循环。对循环结束进行适当处理;有的循环程序可以没有这部分。为执行下一个循环而修改某些参数,尤其循环控制变量的修改等。第42页/共64页442023/1/17用计数控制循环

适用于已知循环次数的循环程序设计

例4‑4从x单元开始的30个连续字单元中存放有30个无符号数,从中找出最大者送入y单元中。分析:根据题意,把第一个数先送入Rx寄存器,将Rx中的数与后面的29个数逐个进行比较,如果Rx中的数较小,则将该较大的数送入Rx;继续与余下的数据逐个比较。在比较过程中,Rx中始终保持较大的数,共计比较29次,则最终Rx

中保留了最大数,最后把Rx中的数(最大者)送入y单元。 AREAmax,CODE,READONLY ;代码段的名字max ENTRY ;程序的入口

CODE32num EQU 29;比较的次数start LDR R0,=x;R0指向源数据块x LDR R1,=y;R1指向单元y LDR R2,=num;R2作为计数器

LDR R3,[R0];将源数据块x中第一个数加载到R3中compare ADD R0,R0, #;每进行一次比较,将R0指针地址加4 LDR R4,[R0];依次将源数据块x中下一个数加载到R4中

CMP R3,R4;比较R3和R4中数的大小

MOVCCR3,R4;如果R3小于R4,则将较大的数送入R3中

SUBS R2,R2,#;计数器值减1 BNE compare;如果不为0,那么继续跳到compare执行

STREQ R3,[R1];如果为0,那么循环比较结束,R3是最大的数

;并且将R3中的数加载到R1指向的单元(即y)中stop MOV r0,#0x18 LDR r1,=0x20026 SWI 0x123456 AREAData,DATA,READWRITEx DCD 73,59,61,34,81,107,225,231,54,43 DCD 100,35,1,42,222,254,34,71,100,31 DCD 33,119,13,44,18,147,55,244,97,3y DCD 0 END第43页/共64页452023/1/17② 适用于已知循环条件的循环程序设计适用于无法确定循环次数,但知道循环结束的条件例4‑5从自然数1开始累加,直到累加和大于1000为止,统计被累加的自然数的个数,并把统计的个数送入n单元,把累加和送入sum单元。分析:根据题意,被累加的自然数的个数事先未知,因此不能用计数方法控制循环。但题目中给定一个条件,即累加和大于1000则停止累加,因此,可以根据这一条件控制循环。我们用R3寄存器放累加和,用R4寄存器放每次取得的自然数,其中它的值也是统计自然数的个数。AREASUM,CODE,READONLY ;代码段的名字SUMENTRY ;程序的入口

CODE32startLDRR0,=n;将数据段中自然数的个数n的地址加载到R0寄存器

LDRR1,=sum;将数据段中自然数的累加和sum的地址加载到R1寄存器

LDRR3,=0;R3存放自然数的累加和

LDRR4,=0;R4用于循环个数的统计/每次取得的自然数

LDRR5,=1000;R5用于循环结束的界限值continueADD R4,R4, #1;取下一个自然数

ADD R3,R3, R4;累加自然数

CMP R3,R5;比较累加和是否超过了1000BCC continue;如果小于1000,那么跳到compare执行

STRCSR3,[R1];如果大于1000,那么将累加和存储到R1所指向的单元中

STRCSR4,[R0];如果大于1000,那么将已累加的自然数个数值存储

;到R0所指向的单元中stopMOVr0,#0x18LDRr1,=0x20026 SWI0x123456

AREAData,DATA,READWRITEn DCD 0 ;定义累加的自然数的个数sum DCD 0 ;定义自然数的累加和

END第44页/共64页462023/1/17双重循环应用举例:冒泡算法对N个单元数据排序!a0a1a2a3a(N-2)a(N-1)数据模型计算法分析:1、每个数据4个字节,内存中连续存放;2、冒泡算法;(同学们可否试描述该算法?)第45页/共64页472023/1/17Data_TAB待排序的数据表头;N表中数据个数;

冒泡排序算法框图第46页/共64页482023/1/174.3.6子程序设计子程序概念

如果在一个程序中的多处用到同一段程序代码,那么可以把这段共同的程序代码抽取出来,写成一个相对独立的程序段,每当需要执行这段代码时,就调用这个程序段,执行完这个程序段后,再返回原来调用它的程序。这样编写程序时,就不必重复写这段代码了,而这样的程序段称为子程序或子过程。子程序的调用与返回主程序中使用BL指令实现子程序的调用

BL 子程序名在子程序结束处,使用如下指令返回到主程序中。

MOV PC, LR主程序与子程序之间的参数传递

主程序调用子程序时,可以向子程序传递一些参数;同样,子程序运行后也可把一些结果参数传回给主程序。主程序与子程序之间的这种信息传递称为参数传递。三种参数传递方式

①寄存器传递参数方式 ②存储区域传递参数方式

③堆栈传递参数方式第47页/共64页492023/1/17寄存器传递参数方式

技术思想:主程序将待传递的数据直接写入约定的通用寄存器,在子程序中直接使用;或子程序返回后,主程序直接从约定的通用寄存器中获得子程序的结果数据。应用特点:这种方式适合于传递较少参数的应用场合。

例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;将R2中的数存储到R0指向的单元中

CMPR2,#0;检查R0的值是否等于0BNEstrcopy;如果不等于0,那么转到strcopy处执行

MOVPC,LR;子程序返回AREAStrings,DATA,READWRITEsrcstrDCB"Firststring-source",0 ;源字符串dststrDCB"Secondstring-destination",0 ;目的字符串

END第48页/共64页502023/1/17存储区域传递参数方式

技术思想:主程序和子程序约定了某一共享内存块用于参数传递,主程序在BL调用子程序前,先将要传递的参数写入到约定的存储单元,子程序可从约定的内存读取这些参数;子程序返回时,也可以使用该方式将数据传给主程序。

应用特点:这种方式可以传递大批量数据。实现方法:当主程序与子程序有较多的数据需要传递时,可以通过共享内存区或传内存数据块地址方式来传递批量数据。通过伪指令ADR直接装载近距离数据块地址;通过伪指令ADRL直接装载中距离数据块地址;通过语句LDRRd,=Label转载远距离的数据块地址;

例4‑6通过设置的入口参数查找函数地址表,实现选择不同的函数功能。说明:本题中通过事先将函数地址存放在存储单元中,通过查找地址表的方法,实现根据“选择项(choice)”进入不同的函数体功能。

第49页/共64页512023/1/17存储区域传递参数方式

AREAJump,CODE,READONLYnumEQU4 ;函数地址表内容的个数

ENTRYCODE32start

LDRR0,=choice ;R0指向存储区的choice单元

LDRR0,[R0] ;设置第一个参数:选择执行哪一个函数

MOVR1,#16 ;设置第1个操作数

MOVR2,#2 ;设置第2个操作数

BLarithfunc ;调用子程序arithfuncstopMOVR0,#0x18 ;程序结束返回编译器调试环境

LDRR1,=0x20026SWI 0x123456arithfuncCMPR0,#num;比较R0的值是否超过函数地址表的个数

MOVHSPC,LR ;如果大于,那么就返回到标号stop处

ADRR3,JumpTable ;将函数地址表的地址作为基地址

LDRPC,[R3,R0,LSL#2] ;根据R0参数进入对应的子程序JumpTable ;函数地址表的入口基地址

DCD DoAdd ;加法子程序

DCD DoSub ;减法子程序

DCD DoMul ;乘法子程序

DCD DoDiv ;除法子程序DoAddADDR0,R1,R2;R0=R1+R2MOVPC,LR ;返回DoSubSUBR0, R1,R2 ;R0=R1-R2MOVPC, LR ;返回DoMul MOVR0,R1,LSLR2 ;R0=R1<<R2MOVPC,LR ;返回DoDiv MOVR0,R1,LSRR2 ;R0=R1>>R2MOVPC,LR ;返回

AREANUM,DATA,READWRITEchoice DCD 3;0:表示选择加法子程序1:表示选择减法子程序

;2:表示选择乘法子程序3:表示选择除法子程序

END第50页/共64页522023/1/17③堆栈传递参数方式

主程序和子程序使用同一个堆栈,主程序在BL调用子程序前,先将要传递的参数压入到堆栈中,子程序可从堆栈中读取传过来的数据;子程序返回需要向主程序传递参数时,也可使用此方法。第51页/共64页532023/1/17第4章目录1.汇编语言的基本概念2.ARM汇编程序的组成与结构3.汇编语言程序设计的基本方法4.汇编语言和C语言交叉编程第52页/共64页542023/1/174.4汇编语言和C语言交叉编程ADS不但支持ARM/Thumb汇编语言程序设计;在微控器模型头文件的支持下,还支持ANSIC和C++语言程序设计,支持对功能寄存器的访问。实际的嵌入式软件中,大部分的代码使用C语言编写。第53页/共64页552023/1/174.4汇编语言和C语言交叉编程C语言支持丰富的抽象数据类型,更便于对目标系统进行数学模型描述和算法描述;编制的程序结构比较好,便于人的理解和维护;大量的支持库可供直接选用。使用C进行程序设计的理由:第54页/共64页562023/1/174.4汇编语言和C语言交叉编程系统底层必须用汇编语言编写(如:启动代码);汇编语言编写的代码执行效率更高;特殊的需求(软件延时)。还要学习汇编语言的理由:第55页/共64页572023/1/174.4汇编语言和C语言交叉编程汇编程序与C程序间的变量互访;汇编程序调用C程序;C程序调用汇编程序;C程序中内嵌汇编程序;本小节主要内容:第56页/共64页582023/1/174.4.1汇编程序与C程序间的变量互访

C程序访问汇编程序中的变量

具体操作步骤:在汇编语言程序中,用伪指令“global”定义全局变量,变量名必须是下划线“_”为首字符的字母数字串;C程序中将该变量声明为外部变量,即可访问汇编程序定义的全局变量。

汇编程序访问C程序中的变量 具体操作步骤:在C程序中,将供汇编程序访问的变量用关键字extern声明为全局外部变量;汇编程序中,用伪指令IMPORT引入C程序中声明的全局变量;使用伪指令LDR读取这个全局变量的地址;使用指令LDR读取这个全局变量的值;在汇编程序中使用这个全局变量;第57页/共64页592023/1/17例:汇编程序和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,READONLY

EXPORTasmVisit ;声明全局函数,供C程序调用??

IMPORTg_var ;引入在C程序中声明定义的全局变量

GLOBAL_multiple ;声明全局变量,供C程序访问asmVisit LDR R0, =g_var LDR R1, [R0] LDR R2, =_multiple LDR R2, [R2] MOV R3, R1,LSLR2 ;将R1中的值扩大指定的倍数

STR R3, [R0] MOV PC, LR AREAasmData,DATA,READWRITE_multipleDCD2 END第58页/共64页602023/1/172.汇编程序调用C程序

汇编程序中调用C函数,只需在汇编程序中用伪指令IMPORT将需要调用的C函数名引用即可,然后将C函数放在一个独立的C文件中进行编译,剩下的工作就由链接器来处理。汇编程序与C函数间参数的传递规则遵守ATPCS(ARMThumbProcedure

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论