嵌入式系统arm汇编语言程序设计课件_第1页
嵌入式系统arm汇编语言程序设计课件_第2页
嵌入式系统arm汇编语言程序设计课件_第3页
嵌入式系统arm汇编语言程序设计课件_第4页
嵌入式系统arm汇编语言程序设计课件_第5页
已阅读5页,还剩58页未读 继续免费阅读

下载本文档

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

文档简介

第四章

ARM汇编语言程序设计4.1汇编语言程序格式4.2ARM汇编器的伪操作4.3汇编语言上机过程4.4汇编语言程序设计4.1汇编语言程序格式4.1.1汇编语言程序的组成

AREAInit,CODE,READONLY ENTRYStart LDR R0, =0x3FF5000 LDR R1, 0xFF STR R1, [R0] LDR R0, =0x3FF5008 LDR R1, 0x01 STR R1, [R0] …. END

AREAInit,CODE,READONLY ENTRYStart LDR R0, =0x3FF5000 LDR R1, 0xFF BL PRINT_TEXT …. ….PRINT_TEXT …. …. MOV PC, LR END

;FULLSEGMENTDEFINITION-----Intel8086 ;-----stacksegment-------- STACK SEGMENT

DB 64DUP(?) STACK ENDS ;-----datasegment-------- DATA SEGMENT ;datadefinitionsareplacedhere DATA ENDS ;-----codesegment-------- CODE SEGMENT MAIN PROCFAR

ASSUMECS:CODE,DS:DATA,SS:STACK MOVAX, DATA MOVDS, AX ------ MOVAH, 4CH INT21H MAIN ENDP CODE ENDS ENDMAIN4.1.2汇编语言的语句格式ARM汇编语言程序的每行语句由1~4部分组成。[LABEL] OPERATION[OPERAND] [;COMMENT]标号域 操作助记符域操作数域 注释域4.2ARM汇编器的伪操作符号定义伪操作(SymbolDefinition)数据定义伪操作(DataDefinition)汇编控制伪操作(AssemblyControl)框架描述伪操作(FrameDescription)其他伪操作(Miscellaneous)数据定义伪操作数据定义伪操作用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。DCB 分配一片连续的字节存储单元并初始化。DCW 分配一片连续的半字存储单元并初始化。DCD 分配一片连续的字存储单元并初始化。SPACE 分配一片连续的存储单元并初始化为0。MAP 定义一个结构化的内存表首地址。FIELD 定义一个结构化的内存表的数据域。DCB格式:标号 DCB 表达式功能:DCB伪操作用于分配一片连续的字节存储单 元,并用伪操作中指定的表达式初始化。其 中,表达式可以为0~255的数值或字符串。 DCB也可以用“=”代替。示例:

Str DCB “Thisisatest!”DCW格式:标号 DCW 表达式功能:DCW伪操作用于分配一片连续的半字存储单 元,并用伪操作中指定的表达式初始化。其 中,表达式可以为程序标号或数值表达式。用 DCW分配的存储单元是半字对齐的。示例:

DataTest DCW 1,2,3DCD格式:标号 DCD 表达式功能:DCD伪操作用于分配一片连续的字存储单 元,并用伪操作中指定的表达式初始化。其 中,表达式可以为程序标号或数值表达式。用 DCD分配的存储单元是字对齐的。DCD也可 以用“&”代替。示例:

Test DCD 4,5,6SPACE格式:标号 SPACE 表达式功能:SPACE伪操作用于分配一片连续的存储区 域并初始化为0。其中,表达式为要分配的字 节数。SPACE也可以用“%”代替。示例:

DataSpace SPACE 100MAP格式:MAP表达式{,基址寄存器}功能:MAP伪操作用于定义一个结构化的内存表首地 址。表达式可以为程序标号或数值表达式,基 址寄存器为可选项,当基址寄存器选项不存在 时,表达式的值即为内存表的首地址。否则, 内存表的首地址为表达式的值与基址寄存器的 和。也可以用“^”代替。示例:

MAP 0x100,R0 ;首地址的值为0x100+R0FIELD格式:标号 FIELD表达式功能:FIELD伪操作用于定义一个结构化的内存表中 的数据域。表达式的值为当前数据域在内存表中 所占的字节数。FIELD伪操作常与MAP配合使用 来定义结构化的内存表。注意:MAP和FIELD仅 用于定义数据结构,并不实际分配存储单元。 FIELD也可以用“#”代替。 由MAP和FIELD配合定义的内存表有3种:(1)表达式是一个基于绝对地址的内存表:MAP 0x100 ;首地址为0x100 A FIELD4 ;A的长度为4字节,位置为0x100 B FIELD4 ;B的长度为4字节,位置为0x104 S FIELD16 ;S的长度为16字节,位置为0x108…. LDR R0, =A ;读取A的地址0x100 LDR R1, [R0] ;将A的内容读到 R1(2)表达式是一个数值,是一个相对地址的内存表:MAP 0x04 ,R9 ;首地址为R9的值

A FIELD4 ;A的长度为4字节,相对位置为0 B FIELD8 ;B的长度为8字节,相对位置为4 S FIELD96 ;S的长度为96字节,相对位置为12 …. LDR R9, =0x900 ;表的首地址为0x904 ADR R0, A ;读取A的地址0x904 LDR R2, [R0] ;将A的内容读到R2 …. LDR R9, =0x2000 ;同一表的首地址为0x2004 ADR R1, B ;读取B的地址0x2008 STR R9, [R1] ;将R9的内容写到B(3)表达式是一个标号,基于PC的内存表:DataSPACE100 ;分配100字节的内存单元初始化0MAP Data ;首地址为Data内存单元

A FIELD4 ;A的长度为4字节,相对位置为0 B FIELD4 ;B的长度为4字节,相对位置为4 S FIELD4 ;S的长度为4字节,相对位置为8…. LDR R5, B ;相当于LDRR5,[PC,#4]

其它常用的伪操作AREA格式:AREA 段名 属性1,属性2,…功能:AREA伪操作定义一个代码段、数据段或特定属性的段。

CODE:定义代码段。

DATA:定义数据段。

READONLY:只读,代码段默认。

READWRITE:可读可写,数据段默认。 一个汇编程序至少包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。

AREA Init,CODE,READONLY ENTRY … B START AREA Stack,DATA,READWRITE SAVE SPACE 20 AREA Init,CODE,READONLY START ADD R1,R2,R3 … … B STARTALIGN格式:ALIGN [表达式[,偏移量]功能:ALIGN可通过添加填充字节的方式,使当前位置满足一定的对齐方式。其中,表达式的值用于指定对齐方式,可能取的值为2的幂,如1、2、4、8、16等。如果没有指定表达式,则将当前位置对齐到下一个字的位置。

… ADD R0,R4,R5 B STARTDATA1 DCB “strin” ALIGN4START LDR R0,[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语言编程模块化的程序设计

(从功能分析——战略上)汇编语言程序设计的基本方法(战术上看)程序设计步骤(对每一模块)

1.问题定义

2.算法设计

3.选择指令

4.编写程序结构化程序设计(算法设计)

1.

顺序结构

2.分支结构

3.

循环结构

4.子程序设计上机过程(具体实现)

1.

编辑程序

2.

汇编源程序

3.

链接程序

4.

调试源程序结构化程序设计概述:

写任何程序最成功的方式是先人工的解决问题——找出算法!

用结构

IF—THEN—ELSE, CASE, REPEAT—UNTIL, WHILE—DO,

FOR—DO

写算法,然后再将该算法翻译成一种合适的程序设计语言——结构化的程序设计!程序设计步骤

1.问题的定义 仔细思考程序所要解决的问题,即用自然语言描述“做什么?以及程序做这些工作时的时序” 如:1.从传感器读取温度值。

2.加上调整因子。

3.将结果存储在存储单元里。

2.算法及表示方法 用来表示程序设计问题的操作序列或步骤——算法,即“怎样做?”。表示方法:1)流程图

2)伪指令3.选择适当的指令(按功能) 一、数据传送类指令 二、算术运算指令 三、逻辑操作指令 四、程序控制指令4.编写程序(从算法到程序)(1)建立算法使用的数据结构

1)数据将存放在存储器还是存放在寄存器中?

2)数据类型是字节、半字或字?

3)有多少数据项?

4)数据为无符号数还是符号数?(2)在代码段开始处写出变量、段寄存器、外围设备等所需要的初始化指令(3)选择实现算法中每一主要动作所需要的指令,并决定数据在这些指令中的存放形式。(4)按照主要指令的要求,用LDR、STR指令或MOV指令把数据送到正确的位置。顺序程序设计: 已知32位变量X、Y存放在存储器的地址0x90010、0x90014中,要求实现Z=X+Y,并且Z的值存放在0x90018中。

AREA Exam,CODE,READONLY ENTRYSTART LDR R0,=0x90010 LDR R1,[R0],#4 LDR R2,[R0],#4 ADD R1,R1,R2 STR R1,[R0] END分支程序设计: 已知32位有符号数X存放在存储器的地址0x90010中,要求实现:

Y=X(X〉=0)或Y=-X(X<0)

AREAExamCODEREADONLY ENTRYSTART LDR R1,=0x90010 LDR R2,[R1] MOV R0,#0 CMP R2,R0

SUBLT R2,R0,R2 STR R2,[R1] END 已知32位有符号数X存放在存储器的地址0x90010中,要求实现:Y=1(X〉0)或Y=0(X=0)或Y=-1(X<0)

AREAExamCODEREADONLY ENTRYSTART LDR R1,=0x90010 LDR R2,[R1] CMP R2,#0 BEQ ZERO BGT PLUS MOV R0,#-1 B FINISHLPUS

MOV R0,#1 B FINISH ZERO MOV R0,#0 FINISH STR R0,[R1] END多分支结构:

main(int){ switch(x){ case0:returnmethod_0(); case1:returnmethod_1(); case2:returnmethod_2(); case3:returnmethod_3(); default:returnmethod_d; }}

AREAExamCODEREADONLY ENTRYSTART CMP R0,#4 ADDLTPC,PC,R0,LSL#2 ;分支表结构其偏

B method_d

;移量由R0决定

B method_0 B method_1 B method_2 B method_3

method_0 MOV R0,#1 B end0 method_1 MOV R0,#2 B end0 method_2 MOV R0,#3 B end0 method_3 MOV R0,#4 B end0

method_d MOV R0,#0 end0 B START END

ENTRY ;markthefirstinstructiontocallstart MOVr0,#1 ;setupthethreeparameters MOVr1,#3 MOVr2,#2 BLarithfunc ;callthefunctionstop MOVr0,#0x18 ;angel_SWIreason_ReportException LDRr1,=0x20026 ;ADP_Stopped_ApplicationExit SWI0x123456 ;ARMsemihostingSWIarithfunc ;labelthefunction CMPr0,#num ;Treatfunctioncodeasunsignedinteger MOVHSpc,lr ;Ifcodeis>=numthensimplyreturn ADRr3,JumpTable ;Loadaddressofjumptable LDRpc,[r3,r0,LSL#2] ;JumptotheappropriateroutineJumpTable DCDDoAdd DCDDoSubDoAdd ADDr0,r1,r2 ;Operation0 MOVpc,lr ;ReturnDoSub SUBr0,r1,r2 ;Operation1 MOVpc,lr ;Return END ;marktheendofthisfile循环程序设计:计数控制:当循环次数已知时,通常使用计数控制法。

MOV Rn,#N ;循环初值部分

… LOOPA … ;循环体

… … SUBS Rn,Rn,#1 ;修改部分

CMP Rn,#0 BGT LOOPA ;控制部分 直到Rn=0时,循环结束。

另,每循环一次计数其加一,直到与设定的值相等时结束。

MOV Rn,#0 ;循环初值部分

… LOOPA … ;循环体

… … ADDS Rn,Rn,#1 ;修改部分

CMP Rn,#N BNE LOOPA ;控制部分 直到Rn=N时,循环结束。例如:编制程序使S=1+2*3+3*4+4*5+…+N(N+1),直到N等于10为止。

AREA Exam,CODE,READONLY ENTRYSTART MOV R0,#1 ;R0累加,置初值1,S MOV R1,#2 ;R1第一个乘数置为2,NREPEAT ADD R2,R1,#1 ;R2第二个乘数,N+1 MUL R3,R2,R1 ;N(N+1)存于R3 ADD R0,R0,R3 ;将部分积累加到R0 ADD R1,R1,#1 ;修改循环次数

CMP R1,#10 BLE REPEAT B START END条件控制:有些情况下,循环次数事先无法确定,但它与某些条件有关。例如:求两个数组DATA1、DATA2对应的数据之和,并将和存入新数组SUM中,计算一直到两数之和为零时结束,并把新数组的长度存于R0中。

AREA BlockData,DATA,READWRITEDATA1 DCD 2,5,0,3,-4,5,0,10,9DATA2 DCD 3,5,4,-2,0,8,3,-10,5SUM DCD 0,0,0,0,0,0,0,0,0

AREA,Exam,CODE,READONLY ENTRYSTART LDR R1,=DATA1 LDR R2,=DATA2 LDR R3,=SUM MOV R0,#0LOOP LDR R4,[R1],#4 LDR R5,[R2],#4 ADDS R4,R4,R5 ADD R0,R0,#1 STR R4,[R3],#4 BNE LOOP B START END 多重循环:即循环体内嵌套循环。设计时可以从外层循环到内层循环,一层一层的进行。通常在设计外层时,仅把内层看成一个处理粗框,然后再将该粗框细化成置初值、工作、修改和控制等四个部分。例:在以BUF为首地址的字存储区中存放有10个无符号数0x0FF,0x00,0x40,0x10,0x90,0x20,0x80,0x30,0x50,0x70,0x60现需将他们按从小到大的顺序排列在BUF中,使编写其程序。分析:“冒泡排序法”。 寄存器分配如下:

R0:指示缓冲区初始地址

R1:外循环计数器

R2:内循环计数器

R3:外循环地址指针

R4:内循环地址指针

R5:内循环下一个数地址指针

R6:存放内循环一轮比较的最小值

R7:存放内循环取出的下一个比较值源程序如下:

AREA BlockData,DATA,READWRITEBUF DCD0x0FF,0x00,0x40,0x10,0x90,0x20,0x80, 0x30,0x50,0x70,0x60N EQU 10

AREA Exam,CODE,READONLY ENTRYSTART LDR R0,=BUF ;指向数组的首地址

MOV R1,#0 ;外循环计数器

MOV R2,#0 ;内循环计数器LOOPI ADD R3,R0,R1,LSL#2 ;外循环首地址放入R3 MOV R4,R3 ;内循环首地址放入R4 ADD R2,R1,#1 ;内循环计数器初值

MOV R5,R4 ;内循环下一地址初值

LDR R6,[R4] ;取内循环第一个值R4LOOPJ ADD R5,R5,#4 ;内循环下一地址值

LDR R7,[R5] ;取出下一地址值R7 CMP R6,R7 ;比较

BLT NEXT ;小则取下一个

SWP R7,R6,[R5] ;大则交换,最小值R6 MOV R6,R7 NEXT ADD R2,R2,#1 ;内循环计数器

CMP R2,#N ;循环终止条件

BLT LOOPJ ;小于N则继续内循环,实现比较一轮

SWP R7,R6,[R3] ;否则,内循环一轮结束, ;将最小数存入外循环的首地址处

ADD R1,R1,#1 ;外循环计数

CMP R1,#N-1 ;外循环终止条件

BLT LOOPI ;小于N-1继续执行外循环

B START END程序运行的结果:00H,10H,20H,30H,40H,50H,60H,70H,80H,90H,0FFH4.3.3子程序设计保护现场、参数传递、恢复现场、子程序返回

AREA Exam,CODE,READONLY ENTRYSTART LDR R0,=0x3FF5000 LDR R1,=0x3FF5008

STMFDR13!,{R0-R2,R14} BL Print_Text …Print_Text … …

LDMFDR13!,{R0-R2,PC} MOV PC,R14 END4.3.4模式切换程序设计处理器模式说明备注USR正常程序运行的工作模式不能直接切换到其它模式特权模式SYS用于支持操作系统的特权任务等可直接切换到其它模式异常模式SVC操作系统使用的一种保护模式只有在系统复位和软件中断响应时,才进入此模式FIQ快速中断请求处理只有在FIQ异常响应时,才进入此模式IRQ中断请求处理只有在IRQ异常响应时,才进入此模式ABT用于虚拟内存和存储器保护在ARM7内核中没有用UND支持软件仿真的硬件协处理器只有在位定义指令异常响应时,才进入此模式处理器工作在什么模式下是由状态寄存器CPSR的模式位M[4:0]来决定的。注意:某些组合会导致处理器进入一个不可恢复的状态。要实现模式之间的切换只需通过专用指令MRS、MSR修改CPSR模式位即可实现。例:堆栈初始化的子程序:InitStack MOV R0,LR ;R0<-LR保存返回地址 ;切换到管理模式并设置其堆栈

MSR CPSR_c,#0xd3 ;CPSR[4:0]<-10011 LDR SP,STACKSVC ;STACKSVC堆栈地址 ;切换到中断模式并设置其堆栈

MSR CPSR_c,#0xd2 ;CPSR[4:0]<-10010 LDR SP,STACKIRQ ;STACKIRQ堆栈地址 ;切换到快中断模式并设置其堆栈

MSR CPSR_c,#0xd1 ;CPSR[4:0]<-10001 LDR SP,STACKFIQ ;STACKFIQ堆栈地址 ;切换到中止模式并设置其堆栈

MSR CPSR_c,#0xd7 ;CPSR[4:0]<-10111 LDR SP,STACKABT ;STACKABT堆栈地址 ;切换到未定义模式并设置其堆栈

MSR CPSR_c,#0xdb ;CPSR[4:0]<-11011 LDR SP,STACKUND ;STACKUND堆栈地址 ;切换到系统模式并设置其堆栈

MSR CPSR_c,#0xdf ;CPSR[4:0]<-11111 LDR SP,STACKSYS ;STACKSYS堆栈地址

MOVPC,R0 ;调用返回4.3.5汇编语言和C语言编程在实际编程时,程序的初始化部分用汇编语言完成,用C或C++完成主要的编程任务。为了保证程序调用时参数传递的正确性,汇编语言程序的设计要遵守APCS(ARMProduceCallStandard),这些基本规则包括子程序调用过程中寄存器的使用规则、堆栈的使用规则以及参数传递规则等。APCS: (1)寄存器的使用规则 (2)堆栈的使用规则 (3)参数传递使用规则(1)寄存器的使用规则子程序间通过寄存器R0-R3来传递参数,记作A0-A3。被调用的子程序在返回前无需恢复寄存器R0-R3的内容—也即这些寄存器的值是由调用者保存的。子程序使用R4-R11寄存器来保存局部变量,记作V1-V8。如果被调用的子程序要用到R4-R11,在进入时要保存这些寄存器的值—压栈,使用完后在返回前必须恢复这些寄存器的值—出栈,也即这些寄存器的值是由被调用者保存的。寄存器R12用作子程序间临时寄存器,记作IP。寄存器R13用作数据栈指针,记作SP,不能用作他用。在子程序进入和退出时SP的值必须相等。寄存器R14称为链接寄存器,记作LR。它用作保存子程序的返回地址。寄存器R15是程序计数器,记作PC。不能用作其他用途。寄存器别名特殊名称使用规则R0A1参数/结果/临时寄存器1R1A2参数/结果/临时寄存器2R2A3参数/结果/临时寄存器3R3A4参数/结果/临时寄存器4R4V1局部变量寄存器1R5V2局部变量寄存器2R6V3局部变量寄存器3R7V4局部变量寄存器4R8V5局部变量寄存器5R9V6局部变量寄存器6R10V7SL局部变量寄存器7/堆栈限制指针R11V8FP帧指针R12IP子程序内部调用的临时寄存器R13SP堆栈指针R14LR链接寄存器R15PC程序寄存器(2)堆栈的使用规则只要有一个函数被调用,在堆栈中就产生一个新的活动帧,其中包含回溯记录、局部变量等。堆栈可分为满栈和空栈,当栈指针指向最后一个入栈的数据元素时,成为满栈。否则称为空栈。根据栈的增长方向不同可以分为递增栈和递减栈。 满递减栈(FullDescending) 空递减栈(EmptyDescending) 满递增栈(FullAscending) 空递增栈(EmptyAscending)ATPCS规定堆栈为FD类型,并且对堆栈的操作是8字节对齐的。(3)参数传递使用规则对于参数可变的子程序,当参数不超过4个时,可以使用寄存器R0~R3来传递;当参数超过4个时,将剩余的参数用堆栈来传

温馨提示

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

评论

0/150

提交评论