ARM汇编语言程序设计.ppt

上传人:小飞机 文档编号:5415693 上传时间:2023-07-05 格式:PPT 页数:63 大小:302.50KB
返回 下载 相关 举报
ARM汇编语言程序设计.ppt_第1页
第1页 / 共63页
ARM汇编语言程序设计.ppt_第2页
第2页 / 共63页
ARM汇编语言程序设计.ppt_第3页
第3页 / 共63页
ARM汇编语言程序设计.ppt_第4页
第4页 / 共63页
ARM汇编语言程序设计.ppt_第5页
第5页 / 共63页
点击查看更多>>
资源描述

《ARM汇编语言程序设计.ppt》由会员分享,可在线阅读,更多相关《ARM汇编语言程序设计.ppt(63页珍藏版)》请在三一办公上搜索。

1、第四章 ARM汇编语言程序设计,4.1 汇编语言程序格式4.2 ARM汇编器的伪操作4.3 汇编语言上机过程4.4 汇编语言程序设计,4.1 汇编语言程序格式,4.1.1 汇编语言程序的组成AREA Init,CODE,READONLYENTRYStartLDRR0,=0 x3FF5000LDRR1,0 xFFSTRR1,R0LDRR0,=0 x3FF5008LDRR1,0 x01STRR1,R0.END,AREA Init,CODE,READONLYENTRYStartLDRR0,=0 x3FF5000LDRR1,0 xFFBLPRINT_TEXT.PRINT_TEXT.MOVPC,LREN

2、D,;FULL SEGMENT DEFINITION-Intel 8086;-stack segment-STACKSEGMENT DB64 DUP(?)STACK ENDS;-data segment-DATASEGMENT;data definitions are placed hereDATAENDS;-code segment-CODESEGMENTMAIN PROC FAR ASSUME CS:CODE,DS:DATA,SS:STACK MOV AX,DATA MOV DS,AX-MOV AH,4CH INT 21HMAIN ENDPCODEENDS END MAIN,4.1.2 汇

3、编语言的语句格式,ARM汇编语言程序的每行语句由14部分组成。LABELOPERATION OPERAND;COMMENT标号域操作助记符域 操作数域注释域,4.2 ARM汇编器的伪操作,符号定义伪操作(Symbol Definition)数据定义伪操作(Data Definition)汇编控制伪操作(Assembly Control)框架描述伪操作(Frame Description)其他伪操作(Miscellaneous),数据定义伪操作,数据定义伪操作用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。DCB分配一片连续的字节存储单元并初始化。DCW分配一片连续的半字存储单元

4、并初始化。DCD分配一片连续的字存储单元并初始化。SPACE分配一片连续的存储单元并初始化为0。MAP定义一个结构化的内存表首地址。FIELD定义一个结构化的内存表的数据域。,DCB格式:标号 DCB表达式功能:DCB伪操作用于分配一片连续的字节存储单元,并用伪操作中指定的表达式初始化。其中,表达式可以为0255的数值或字符串。DCB也可以用“=”代替。示例:StrDCB“This is a test!”,DCW格式:标号 DCW表达式功能:DCW伪操作用于分配一片连续的半字存储单元,并用伪操作中指定的表达式初始化。其中,表达式可以为程序标号或数值表达式。用DCW分配的存储单元是半字对齐的。示

5、例:DataTestDCW 1,2,3,DCD格式:标号 DCD表达式功能:DCD伪操作用于分配一片连续的字存储单元,并用伪操作中指定的表达式初始化。其中,表达式可以为程序标号或数值表达式。用DCD分配的存储单元是字对齐的。DCD也可 以用“&”代替。示例:TestDCD4,5,6,SPACE格式:标号 SPACE表达式功能:SPACE伪操作用于分配一片连续的存储区域并初始化为0。其中,表达式为要分配的字节数。SPACE也可以用“%”代替。示例:DataSpace SPACE100,MAP格式:MAP 表达式,基址寄存器功能:MAP伪操作用于定义一个结构化的内存表首地址。表达式可以为程序标号或

6、数值表达式,基址寄存器为可选项,当基址寄存器选项不存在时,表达式的值即为内存表的首地址。否则,内存表的首地址为表达式的值与基址寄存器的和。也可以用“”代替。示例:MAP0 x100,R0;首地址的值为0 x100+R0,FIELD格式:标号 FIELD 表达式 功能:FIELD伪操作用于定义一个结构化的内存表中的数据域。表达式的值为当前数据域在内存表中所占的字节数。FIELD伪操作常与MAP配合使用来定义结构化的内存表。注意:MAP和FIELD仅用于定义数据结构,并不实际分配存储单元。FIELD也可以用“#”代替。由MAP和FIELD配合定义的内存表有3种:,(1)表达式是一个基于绝对地址的内

7、存表:MAP0 x100;首地址为0 x100AFIELD 4;A的长度为4字节,位置为0 x100BFIELD 4;B的长度为4字节,位置为0 x104SFIELD 16;S的长度为16字节,位置为0 x108.LDRR0,=A;读取A的地址0 x100LDRR1,R0;将A的内容读到R1,(2)表达式是一个数值,是一个相对地址的内存表:MAP0 x04,R9;首地址为R9的值AFIELD 4;A的长度为4字节,相对位置为0BFIELD 8;B的长度为8字节,相对位置为4SFIELD 96;S的长度为96字节,相对位置为12.LDRR9,=0 x900;表的首地址为0 x904ADRR0,A

8、;读取A的地址0 x904LDRR2,R0;将A的内容读到R2.LDRR9,=0 x2000;同一表的首地址为0 x2004ADRR1,B;读取B的地址0 x2008STRR9,R1;将R9的内容写到B,(3)表达式是一个标号,基于PC的内存表:Data SPACE 100;分配100字节的内存单元初始化0MAPData;首地址为Data内存单元AFIELD 4;A的长度为4字节,相对位置为0BFIELD 4;B的长度为4字节,相对位置为4SFIELD 4;S的长度为4字节,相对位置为8.LDRR5,B;相当于LDR R5,PC,#4,其它常用的伪操作,AREA格式:AREA段名属性1,属性2

9、,功能:AREA伪操作定义一个代码段、数据段或特定属性的段。CODE:定义代码段。DATA:定义数据段。READONLY:只读,代码段默认。READWRITE:可读可写,数据段默认。一个汇编程序至少包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。,AREAInit,CODE,READONLYENTRYBSTARTAREAStack,DATA,READWRITESAVESPACE20AREAInit,CODE,READONLYSTARTADDR1,R2,R3BSTART,ALIGN格式:ALIGN表达式,偏移量功能:ALIGN可通过添加填充字节的方式,使当前位置满足一定的对齐方式。

10、其中,表达式的值用于指定对齐方式,可能取的值为2的幂,如1、2、4、8、16等。如果没有指定表达式,则将当前位置对齐到下一个字的位置。ADDR0,R4,R5BSTARTDATA1DCB“strin”ALIGN 4STARTLDRR0,R5,4.3 汇编语言上机过程,1.编辑汇编语言源程序2.编译源程序3.链接汇编程序4.调试汇编程序,4.4 汇编语言程序设计,4.3.1 程序设计步骤4.3.2 简单程序设计(顺序、分支、循环)4.3.3 子程序设计4.3.4 模式切换程序设计4.3.5 汇编语言和C语言编程,模块化的程序设计(从功能分析战略上),汇编语言程序设计的基本方法(战术上看)程序设计步

11、骤(对每一模块)1.问题定义2.算法设计3.选择指令4.编写程序结构化程序设计(算法设计)1.顺序结构2.分支结构 3.循环结构4.子程序设计上机过程(具体实现)1.编辑程序2.汇编源程序3.链接程序4.调试源程序,结构化程序设计概述:写任何程序最成功的方式是先人工的解决问题找出算法!用结构IFTHENELSE,CASE,REPEATUNTIL,WHILEDO,FORDO写算法,然后再将该算法翻译成一种合适的程序设计语言结构化的程序设计!,程序设计步骤 1.问题的定义仔细思考程序所要解决的问题,即用自然语言描述“做什么?以及程序做这些工作时的时序”如:1.从传感器读取温度值。2.加上调整因子。

12、3.将结果存储在存储单元里。2.算法及表示方法用来表示程序设计问题的操作序列或步骤算法,即“怎样做?”。表示方法:1)流程图 2)伪指令,3.选择适当的指令(按功能)一、数据传送类指令二、算术运算指令三、逻辑操作指令四、程序控制指令4.编写程序(从算法到程序),(1)建立算法使用的数据结构 1)数据将存放在存储器还是存放在寄存器中?2)数据类型是字节、半字或字?3)有多少数据项?4)数据为无符号数还是符号数?,(2)在代码段开始处写出变量、段寄存器、外围设备等所需要的初始化指令(3)选择实现算法中每一主要动作所需要的指令,并决定数据在这些指令中的存放形式。(4)按照主要指令的要求,用LDR、S

13、TR指令或MOV指令把数据送到正确的位置。,顺序程序设计:已知32位变量X、Y存放在存储器的地址0 x90010、0 x90014中,要求实现Z=X+Y,并且Z的值存放在0 x90018中。AREAExam,CODE,READONLYENTRYSTARTLDRR0,=0 x90010LDRR1,R0,#4LDRR2,R0,#4ADDR1,R1,R2STRR1,R0END,分支程序设计:已知32位有符号数X存放在存储器的地址0 x90010中,要求实现:Y=X(X=0)或 Y=-X(X0)AREA Exam CODE READONLYENTRYSTARTLDRR1,=0 x90010LDRR2,

14、R1MOVR0,#0CMPR2,R0SUBLT R2,R0,R2STRR2,R1END,已知32位有符号数X存放在存储器的地址0 x90010中,要求实现:Y=1(X0)或 Y=0(X=0)或Y=-1(X0)AREA Exam CODE READONLYENTRYSTARTLDRR1,=0 x90010LDRR2,R1CMPR2,#0BEQZEROBGTPLUSMOVR0,#-1BFINISHLPUSMOVR0,#1BFINISH ZEROMOVR0,#0FINISHSTRR0,R1END,多分支结构:main(int)switch(x)case 0:return method_0();cas

15、e 1:return method_1();case 2:return method_2();case 3:return method_3();default:return method_d;,AREA Exam CODE READONLYENTRYSTARTCMPR0,#4ADDLT PC,PC,R0,LSL#2;分支表结构其偏Bmethod_d;移量由R0决定Bmethod_0Bmethod_1Bmethod_2Bmethod_3,method_0MOVR0,#1Bend0method_1MOVR0,#2Bend0method_2MOVR0,#3Bend0method_3MOVR0,#4B

16、end0method_dMOVR0,#0end0BSTARTEND,ENTRY;mark the first instruction to callstart MOV r0,#1;set up the three parameters MOV r1,#3 MOV r2,#2 BL arithfunc;call the functionstop MOV r0,#0 x18;angel_SWIreason_ReportException LDR r1,=0 x20026;ADP_Stopped_ApplicationExit SWI 0 x123456;ARM semihosting SWIari

17、thfunc;label the function CMP r0,#num;Treat function code as unsigned integer MOVHS pc,lr;If code is=num then simply return ADR r3,JumpTable;Load address of jump table LDR pc,r3,r0,LSL#2;Jump to the appropriate routineJumpTable DCD DoAdd DCD DoSubDoAdd ADD r0,r1,r2;Operation 0 MOV pc,lr;ReturnDoSub

18、SUB r0,r1,r2;Operation 1 MOV pc,lr;Return END;mark the end of this file,循环程序设计:,计数控制:当循环次数已知时,通常使用计数控制法。MOVRn,#N;循环初值部分LOOPA;循环体SUBSRn,Rn,#1;修改部分CMPRn,#0BGTLOOPA;控制部分直到Rn=0时,循环结束。,另,每循环一次计数其加一,直到与设定的值相等时结束。MOVRn,#0;循环初值部分LOOPA;循环体ADDSRn,Rn,#1;修改部分CMPRn,#NBNELOOPA;控制部分直到Rn=N时,循环结束。,例如:编制程序使S=1+2*3+3*

19、4+4*5+N(N+1),直到N等于10为止。AREAExam,CODE,READONLYENTRYSTARTMOVR0,#1;R0累加,置初值1,SMOVR1,#2;R1第一个乘数置为2,NREPEATADDR2,R1,#1;R2第二个乘数,N+1MULR3,R2,R1;N(N+1)存于R3ADDR0,R0,R3;将部分积累加到R0ADDR1,R1,#1;修改循环次数CMPR1,#10BLEREPEATBSTARTEND,条件控制:有些情况下,循环次数事先无法确定,但它与某些条件有关。例如:求两个数组DATA1、DATA2对应的数据之和,并将和存入新数组SUM中,计算一直到两数之和为零时结束

20、,并把新数组的长度存于R0中。AREABlockData,DATA,READWRITEDATA1DCD2,5,0,3,-4,5,0,10,9DATA2DCD3,5,4,-2,0,8,3,-10,5SUMDCD0,0,0,0,0,0,0,0,0,AREA,Exam,CODE,READONLYENTRYSTARTLDRR1,=DATA1LDRR2,=DATA2LDRR3,=SUMMOVR0,#0LOOPLDRR4,R1,#4LDRR5,R2,#4ADDSR4,R4,R5ADDR0,R0,#1STRR4,R3,#4BNELOOPBSTARTEND,多重循环:,即循环体内嵌套循环。设计时可以从外层循环

21、到内层循环,一层一层的进行。通常在设计外层时,仅把内层看成一个处理粗框,然后再将该粗框细化成置初值、工作、修改和控制等四个部分。例:在以BUF为首地址的字存储区中存放有10个无符号数0 x0FF,0 x00,0 x40,0 x10,0 x90,0 x20,0 x80,0 x30,0 x50,0 x70,0 x60现需将他们按从小到大的顺序排列在BUF中,使编写其程序。分析:“冒泡排序法”。寄存器分配如下:,R0:指示缓冲区初始地址R1:外循环计数器R2:内循环计数器R3:外循环地址指针R4:内循环地址指针R5:内循环下一个数地址指针R6:存放内循环一轮比较的最小值R7:存放内循环取出的下一个比

22、较值源程序如下:AREABlockData,DATA,READWRITEBUFDCD 0 x0FF,0 x00,0 x40,0 x10,0 x90,0 x20,0 x80,0 x30,0 x50,0 x70,0 x60NEQU10,AREAExam,CODE,READONLY ENTRYSTART LDRR0,=BUF;指向数组的首地址 MOVR1,#0;外循环计数器 MOVR2,#0;内循环计数器LOOPI ADDR3,R0,R1,LSL#2;外循环首地址放入R3 MOVR4,R3;内循环首地址放入R4 ADDR2,R1,#1;内循环计数器初值 MOVR5,R4;内循环下一地址初值 LDRR

23、6,R4;取内循环第一个值R4LOOPJ ADDR5,R5,#4;内循环下一地址值 LDRR7,R5;取出下一地址值R7 CMPR6,R7;比较 BLTNEXT;小则取下一个 SWPR7,R6,R5;大则交换,最小值R6 MOVR6,R7,NEXTADDR2,R2,#1;内循环计数器CMPR2,#N;循环终止条件BLTLOOPJ;小于N则继续内循环,实现比较一轮SWPR7,R6,R3;否则,内循环一轮结束,;将最小数存入外循环的首地址处ADDR1,R1,#1;外循环计数CMPR1,#N-1;外循环终止条件BLTLOOPI;小于N-1继续执行外循环BSTARTEND程序运行的结果:00H,10H

24、,20H,30H,40H,50H,60H,70H,80H,90H,0FFH,4.3.3 子程序设计,保护现场、参数传递、恢复现场、子程序返回AREAExam,CODE,READONLYENTRYSTARTLDRR0,=0 x3FF5000LDRR1,=0 x3FF5008STMFD R13!,R0-R2,R14 BLPrint_TextPrint_TextLDMFD R13!,R0-R2,PC MOVPC,R14END,4.3.4 模式切换程序设计,处理器工作在什么模式下是由状态寄存器CPSR的模式位M4:0来决定的。注意:某些组合会导致处理器进入一个不可恢复的状态。要实现模式之间的切换只需通

25、过专用指令MRS、MSR修改CPSR模式位即可实现。例:堆栈初始化的子程序:InitStack MOVR0,LR;R0-LR保存返回地址;切换到管理模式并设置其堆栈MSRCPSR_c,#0 xd3;CPSR4:0-10011LDRSP,STACKSVC;STACKSVC堆栈地址,;切换到中断模式并设置其堆栈MSRCPSR_c,#0 xd2;CPSR4:0-10010LDRSP,STACKIRQ;STACKIRQ堆栈地址;切换到快中断模式并设置其堆栈MSRCPSR_c,#0 xd1;CPSR4:0-10001LDRSP,STACKFIQ;STACKFIQ堆栈地址;切换到中止模式并设置其堆栈MSR

26、CPSR_c,#0 xd7;CPSR4:0-10111LDRSP,STACKABT;STACKABT堆栈地址;切换到未定义模式并设置其堆栈MSRCPSR_c,#0 xdb;CPSR4:0-11011LDRSP,STACKUND;STACKUND堆栈地址;切换到系统模式并设置其堆栈MSRCPSR_c,#0 xdf;CPSR4:0-11111LDRSP,STACKSYS;STACKSYS堆栈地址MOV PC,R0;调用返回,4.3.5 汇编语言和C语言编程,在实际编程时,程序的初始化部分用汇编语言完成,用C或C+完成主要的编程任务。为了保证程序调用时参数传递的正确性,汇编语言程序的设计要遵守APC

27、S(ARM Produce Call Standard),这些基本规则包括子程序调用过程中寄存器的使用规则、堆栈的使用规则以及参数传递规则等。APCS:(1)寄存器的使用规则(2)堆栈的使用规则(3)参数传递使用规则,(1)寄存器的使用规则子程序间通过寄存器R0-R3来传递参数,记作A0-A3。被调用的子程序在返回前无需恢复寄存器R0-R3的内容也即这些寄存器的值是由调用者保存的。子程序使用R4-R11寄存器来保存局部变量,记作V1-V8。如果被调用的子程序要用到R4-R11,在进入时要保存这些寄存器的值压栈,使用完后在返回前必须恢复这些寄存器的值出栈,也即这些寄存器的值是由被调用者保存的。寄

28、存器R12用作子程序间临时寄存器,记作IP。寄存器R13用作数据栈指针,记作SP,不能用作他用。在子程序进入和退出时SP的值必须相等。寄存器R14称为链接寄存器,记作LR。它用作保存子程序的返回地址。寄存器R15是程序计数器,记作PC。不能用作其他用途。,(2)堆栈的使用规则只要有一个函数被调用,在堆栈中就产生一个新的活动帧,其中包含回溯记录、局部变量等。堆栈可分为满栈和空栈,当栈指针指向最后一个入栈的数据元素时,成为满栈。否则称为空栈。根据栈的增长方向不同可以分为递增栈和递减栈。满递减栈(Full Descending)空递减栈(Empty Descending)满递增栈(Full Asce

29、nding)空递增栈(Empty Ascending)ATPCS规定堆栈为FD类型,并且对堆栈的操作是8字节对齐的。,(3)参数传递使用规则,对于参数可变的子程序,当参数不超过4个时,可以使用寄存器R0R3来传递;当参数超过4个时,将剩余的参数用堆栈来传递,入栈的顺序与参数的顺序相反,最后一个先入栈。结果为一个32位整数时,通过R0返回。结果为一个64位整数时,通过R0、R1返回,依此类推。对于位数更多的结果,需要通过内存来传递。,C程序调用汇编程序示例C语言源程序strtest.c:#include Externvoid Strcopy(char*d,const char*s);int ma

30、in()const char*srcstr=“First string source“;char dststr=“Second string destination“;printf(“Before copying:n“);printf(“%s n%s n”,srcstr,dststr);strcopy(dststr,srcstr);printf(“After copying:n“);printf(“%s n%s n”,srcstr,dststr);return 0;,汇编语言源程序Scopy.sAREAScopy,CODE,READONLYEXPORT strcopyStrcopy;R0指向目

31、标地址;R1指向源地址LDRBR2,R1,#1STRBR2,R0,#1CMPR2,#0BNEStrcopyMOVPC,LREND,汇编程序调用C程序汇编语言调用C程序之前,要用IMPORT伪指令来声明被调用的C程序,并用BL指令来调用。下例中,C语言程序g()完成5个整数相加的功能,汇编程序ARM_add则要调用g()完成5个整数和的功能,参数传递为14个均在R0R3中,第5个参数利用堆栈传送。C语言源程序C_add.c:#include int g(int a,int b,int c,int d,int e);实现5个整数求和 return a+b+c+d+e;,汇编源程序ARM_add.s:AREAARM_add,CODE,READONLYEXPORT ARM_addIMPORT gENTRYSTRLR,SP,#-4!MOVR0,#1MOVR1,#2MOVR2,#3MOVR3,#4MOVR4,#5STRR4,SP,#-4!BLgADDSP,SP,#4LDRPC,SP,#4END,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号