ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础

PPT
  • 阅读 92 次
  • 下载 0 次
  • 页数 76 页
  • 大小 1.044 MB
  • 2022-11-12 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础
可在后台配置第一页与第二页中间广告代码
ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础
可在后台配置第二页与第三页中间广告代码
ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础
可在后台配置第三页与第四页中间广告代码
ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础
ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 76
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
文本内容

【文档说明】ARM嵌入式系统原理与应用-第4章-ARM汇编语言及C语言程序设计基础.pptx,共(76)页,1.044 MB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-2163.html

以下为本文档部分文字说明:

第4章ARM汇编语言及C语言程序设计基础本章内容简介4.1ARM汇编的语句格式4.2ARM汇编的程序结构4.3ARM汇编语言程序设计举例4.4ARMC语言基础及混合编程4.5ARM汇编语言实验基础4.1ARM汇编的语句格式ARM汇编语言基本的的语句

格式如下:符号指令、伪指令或伪操作[;注释]一些相同的基本特征1、一条指令一行。2、使用标号(label)给内存单元提供名称,从第一列开始书写。3、指令必须从第二列或能区分标号的地方开始书写。4、注释跟在指定的注释字符后面(ARM使用的是“;”),一直书写到行尾

。4.1.1符号命名规则1.符号由大小写字母、数字及下划线组成,符号不能用数字开头。2.符号区分大小写,同名的大、小写符号会被编译器认为是两个不同的符号。3.符号在其作用范围内必须唯一。4.自定义的

符号名不能与系统的保留字相同。5.符号名不应与指令或伪指令同名。4.1.2ARM汇编语言伪操作伪操作(Directive)是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,对源程序运行汇编程序处理,而不是在

计算机运行期间由处理器执行。表4-1ARM汇编常用伪操作列表操作符语法格式功能描述ARMARM指示编译器处理的是32位ARM指令CODE32CODE32指示编译器处理的是32位ARM指令THUMBTHUMB指示编译器处理的

是16位THUMB指令CODE16CODE16指示编译器处理的是16位THUMB指令AREAAREAname{attr}{attr}段属性定义ENTRYENTRY声明程序的入口点ENDEND源程序结尾标识EQUnameEQUe

xpr{,type}定义常量或标号名称EXPORTEXPORTname声明全局标号IMPORTIMPORTname外部符号声明4.1.3ARM汇编语言伪指令伪指令是ARM处理器支持的汇编语言程序里的特殊助记符,它不在处理器运

行期间由机器执行,只是在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作。ARM汇编语言伪指令如表3-2所示表4-2ARM汇编语言伪指令列表伪指令语法格式功能ADRADR{cond}regis

ter,=expression它将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。ADRLADRL{cond}register,=expression它将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。LDRLDR{cond}register,

=expression将一个32位的常数或者一个地址值读取到寄存器中,可以看作是加载寄存器的内容。NOPNOPNOP是空操作伪指令,在汇编时将会被替代成ARM中的空操作4.1.3ARM汇编语言伪指令1、ADR伪指令---小范围的地址读取在汇编编译器编译源程序时,ADR伪指令被编译

器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。ADR伪指令中的地址是基于PC或寄存器的,当ADR伪指令中的地址是基于PC时,该地址与ADR伪指令必须在同一个代码段中。4.1

.3ARM汇编语言伪指令示例:LOOPMOVr0,#10;LOOP为行标,指示某一行代码ADRr4,LOOP;将LOOP地址放入r4(相对地址);因为pc值为当前指令地址值加8字节替换成本ADR伪指令将被编译器编译为;SUBr4,PC,#0xc4.1.3ARM汇编语言伪指令

2、ADRL伪指令----中等范围的地址读取地址表达式expr的取值范围:当地址值是字节对齐时,其取指范围为:-64K~64K;当地址值是字对齐时,其取指范围为:-256K~256K;4.1.3ARM汇编语言伪指令示例:LOOPMOVr0,#10;L

OOP为行标,指示某一行代码ADRLr4,LOOP;将LOOP地址放入r4(相对地址);因为pc值为当前指令地址值加8字节替换成本ADR伪指令将被编译器编译为;SUBr4,PC,#0xc;NOP(MOVr0,r0

)4.1.3ARM汇编语言伪指令3、LDR伪指令-----大范围的地址读取在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序

相对偏移的LDR指令从文字池读出常量。4.1.3ARM汇编语言伪指令示例:LDRr1,=0xff;将0xff读取到r1中;编译后得到MOVr1,0xff示例:LDRr1,=ADDR;将外部地址ADDR读取到R1中;汇编后将得到:;LDRr1,[PC,OFFS

ET_TO_LPOOL];…;LPOOLDCDADDR4.2ARM汇编的程序结构在ARM(Thumb)汇编语言程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据。一个汇编

程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映象文件。【例4-1】汇编语言源程序的基本格式AREAEXAMPLE,CODE,READONLY;定义段的名称和属性,表示了一个段的

开始ENTRY;标识程序的入口点start;以下为具体指令MOVR0,#10MOVR1,#3ADDR0,R0,R1END;标识源文件的结束。1、顺序程序设计2、分支程序设计示例CMPR1,#3;比较R1和#3ADDHIR0,R0,R1;ifR1>3thenR0=R0+R

1ADDLSR0,R0,#3;ifR1<3thenR0=R0+3示例CMPR1,#3;比较R1和#3BHIEND;ifR1>3thenENDADDR0,R0,#3;R0=R0+3END示例LOOPADDR0,R0,R1;R0=R0+R1CMPR0

,#3;比较R0和#3BLSLOOP;ifR0<3then跳转到LOOP循环END3、循环程序设计示例┉┉BLPRINT_TEXT;跳转到子程序PRINT_TEXT,并保存PC至LR┉┉PRINT_TEXT;子程序入口┉┉MOVPC,LR;子程序运行完毕将PC置为LR,准备返

回END4、子程序4.3ARM汇编语言程序设计举例【例4-2】实现1+2+……+NNEQU5;;常量的定义AREAExample,CODE,READONLY;定义段名属性等ENTRY;程序入口CODE32;AR

M代码START;行标定义LDRR0,=N;R0赋值MOVR2,R0;R2充当计数器MOVR0,#0;R0←0MOVR1,#0;R1←0LOOP;行标CMPR1,R2;比较R1R2BHIADD_END;如果R1>R2跳转到ADD_END

;分支的实现ADDR0,R0,R1;R0←R0+R1ADDR1,R1,#1;R1←R1+1BLOOP;无条件跳转至LOOP;循环的实现ADD_END;行标定义BADD_END;无条件跳转ADD_ENDEND;代码结束【例4-3】给出了一个输出HelloWorld的程序AREAHe

lloWorld,CODE,READONLY;声明代码段SWI_WriteCEQU&0;输出R0中的字符,&0为预定义的输出代码段入口SWI_ExitEQU&11;程序结束&11为预定义程序结束代码入口ENTRY;代码的入口STARTADRR1,TEXT;R

1→“HelloWorld”LOOPLDRBR0,[R1],#1;读取下一个字节CMPR0,#0;检查文本终点SWINESWI_WriteC;若非终点,则打印BNELOOP;并返回LOOPSWISWI_Exit;执行结束TE

XT=“HelloWorld”,&0a,&0d,0ENDAREABlkCpy,CODE,READONLY;声明代码段SWI_WriteCEQU&0;输出R0中的字符SWI_ExitEQU&11;程序结束ENTRY;代码的入

口ADRR1,TABLE1;R1→TABLE1ADRR2,TABLE2;R2→TABLE2ADRR3,T1END;R3→T1ENDLOOP1LDRR0,[R1],#4;读取TABLE1的第一个字STRR0,[R2],#4;拷贝到

TABLE2CMPR1,R3;结束?BLTLOOP1;若非,则再拷贝ADRR1,TABLE2;R1→TABLE2LOOP2LDRBR0,[R1],#1;读取下一个字CMPR0,#0;检查文本终点SWINESWI_WriteC;若非终点,则打印BNEL

OOP2;并返回LOOP2SWISWI_Exit;执行结束TABLE1=“Thisistherightstring!”,&0a,&0d,0T1ENDALIGN;保证字对准TABLE2=“Thisisthewron

gstring!”,0END;程序源代码结束4.4ARMC语言基础及混合编程4.4.1ATPCS概述4.4.2基本ATPCS4.4.3支持ARM程序和Thumb程序混合使用的ATPCS4.4.4C语言及汇编语言混合编程4.4.1ATPCS概述高级语言使程序能够以抽象

的方式来表述。编译器是支持高级语言、可以达到抽象目的的依赖。灵活地运用汇编语言和C语言之间的关系进行混合编程,有利于系统和相关模块的开发。4.4.1ATPCS概述汇编语言和C语言的混合编程分为两种情况:如果汇编代码比较简单,则可以直接

利用内嵌汇编的方式进行混合编程;如果汇编代码比较复杂,则可以将汇编程序和C程序分别以文件的形式加到一个工程里,通过ATPCS标准来完成汇编程序和C程序之间的调用。4.4.1ATPCS概述为了使不同编译器产生的程序和

汇编语言编写的程序能灵活地混合,ARM公司定义了一系列过程调用的规则,称为ATPCS(ARM-ThumbProcedureCallStandard)。这些基本规则包括子程序调用过程中寄存器的使用规则、数据栈的使用规则和参数的传递规则。4.

4.1ATPCS概述如果程序遵守ATPCS,则程序中ARM子程序和Thumb子程序可互相调用。具体做法是:在编译和汇编时,通过使用/interwork选项可以使编译器生成的目标代码遵守支持ATPCS。对于C程序,编译选项为apcs/interwork。对于汇编程序

,必须保证编写的代码本身遵守ATPCS。4.4.2基本ATPCS基本ATPCS规定了在子程序调用时的一些基本规则,包括以下三个方面的内容:各寄存器的使用规则及其相应的名字;数据栈的使用规则;参数传递的规

则。1.寄存器的使用规则寄存器R0R1R2R3R4R5R6R7R8R9R10R11R12R13R14R15ATPCS名称a1a2a3a4v1v2v3v4WRv5v6SBv7SLv8FPr0-r3:用于传参,r0用于返回值r4-r

11:通用变量寄存器r12:用做过程调用中间临时过渡寄存器r13:堆栈指针r14:连接寄存器r15:PC静态基址寄存器SB,数据栈限制指针SL和桢指针FP被调用的子程序在返回前无需恢复寄存器R0~R3的内容。2)在子程序中,使用R4~R11来保存局部变量,记作:V1~V8。如果在

子程序中使用到V1~V8的某些寄存器,子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值,对于子程序中没有用到的寄存器则不必执行这些操作。3)寄存器R12用作子程序间临时过渡寄存器,记作ip;在子程序的连接代码段中经常会有这种使用规则。

4)寄存器R13用作数据栈指针,记做SP,在子程序中寄存器R13不能用做其他用途。寄存器SP在进入子程序时的值和退出子程序时的值必须相等。5)寄存器R14用作连接寄存器,记作lr;它用于保存子程序的返回地址,如果在子程序中保存了返回地址,则R14可用作其它的用途。6)寄存器R15是程序计数器,记

作PC;它不能用作其他用途。7)ATPCS中的各寄存器在ARM编译器和汇编器中都是预定义的2.数据栈的使用规则;ATPCS规定数据栈为FD类型,并对数据栈的操作是8字节对齐的,下面是一个数据栈的示例及相关的名词。1)数据栈栈指针(stackpointer)2)数据栈的基地址(sta

ckbase)是指数据栈的最高地址。由于ATPCS中的数据栈是FD类型的,实际上数据栈中最早入栈数据占据的内存单元是基地址的下一个内存单元。3)数据栈界限(stacklimit)是指数据栈中可以使用的最低的内存单元地址。4)已占用的数据栈(usedstack)是

指数据栈的基地址和数据栈栈指针之间的区域。其中包括数据栈栈指针对应的内存单元。5)数据栈中的数据帧(stackframes)是指在数据栈中,为子程序分配的用来保存寄存器和局部变量的区域。3.参数传递的规则。1)参数个数可变的子程序参数传递规

则当参数不超过4个时,可以使用寄存器R0~R3来进行参数传递,当参数超过4个时,还可以使用数据栈来传递参数。2)参数个数固定的子程序参数传递规则第一个整数参数通过寄存器R0~R3来传递,其他参数通过数据栈传递。3)子程序结果返回规则:

(1)结果为一个32位的整数时,可以通过寄存器R0返回。(2)结果为一个64位整数时,可以通过R0和R1返回,依此类推。4.4.3ARM程序和Thumb程序的混合使用在编译或汇编时,使用/intework告诉编译器或汇编器生成的目标代码遵

守支持ARM程序和Thumb程序混合使用的ATPCS,它用在以下场合:程序中存在ARM程序调用Thumb程序的情况;程序中存在Thumb程序调用ARM程序的情况;需要连接器来进行ARM状态和Thumb状态切换的情况;在下述情况下使用选项nointer

work:程序中不包含Thumb程序;用户自己进行ARM程序和Thumb程序切换。需要注意的是:在同一个C/C++程序中不能同时有ARM指令和Thumb指令。4.4C语言和ARM汇编语言之间相互调用当链接器发

现有ARM子程序与Thumb子程序相互调用时,编译器将修改相应的调用和返回代码,或者添加一段veneers代码(链接器生成的用于程序状态转换的代码段)来完成程序状态的转换。C语言和ARM汇编语言之间相互调用包含三部分内容:汇编语言程序访问C语言全局变量、C语

言程序调用汇编语言程序、汇编语言程序调用C语言程序。4.4C语言和ARM汇编语言之间相互调用汇编语言程序可通过地址间接访问在C语言程序中声明的全局变量。具体做法是使用IMPORT关键词引入全局变量,再利用LDR和STR指令根据全局变量的地址来进行访问。具体做法是使用IMPORT关

键词引入全局变量,再利用LDR和STR指令根据全局变量的地址来进行访问。汇编语言程序访问C语言全局变量unsignedcharLDRB/STRBunsignedshortLDRH/STRHunsignedintLDR/STRcharLDRSB/STRSBshor

tLDRSH/STRSH对于不同类型的变量,需要选用不同选项的LDR和STR指令,列表如下:对于结构体,如果知道各个成员的偏移量,则可通过LDR/STR指令进行访问。如果结构体所占空间小于8个字,则可用LDM和STM一次性读写。AREAglobals,CODE,READONLYEXPORTas

msubroutine;用EXPORT伪操作声明该变量可被其它文件引用;相当于声明了一个全局变量IMPORTglobvar;globvar是C程序中声明的全局变量;用IMPRORT伪操作声明该变量是在其它文件中定义的;在本

文件中可能要用到该变量asmsubroutineLDRR1,=globvar;从文字池读出globvar的地址,将其保存到R1LDRR0,[R1]ADDR0,R0,#2STRR0,[R1];将修改后的值返回MOVPC,LREND例:4.4C语言和ARM汇编语言之间相互调用首先,为保证程序调用时

参数的正确传递,汇编语言程序的设计要遵守ATPCS。其次,汇编语言程序需要使用EXPORT伪操作声明本程序可被其它程序调用。同时,在C语言程序中使用extern关键词声明来该汇编语言程序。C语言程序调用汇编语言程序1.内嵌汇编内嵌汇编器armcc和armcpp用来支持完整的ARM指令集,tcc和

tcpp用来支持Thumb指令集。内嵌的汇编指令包括大部分ARM指令和Thumb指令,但不能直接引用C语言的变量定义,数据交换必须通过函数过程调用标准ATPCS(ARM-ThumbProcedureCallStandard)进行。嵌

入式汇编在形式上表现为独立定义的函数体。1.内嵌汇编--内嵌汇编指令__asm(“指令[;指令]”);语法格式:◆其中“__asm”是ARMC编译器使用的关键字,“__”是两个下划线。◆指令之间用“;”分隔。◆如果一条指令占据多行,在行尾可使用连字符“

\”。◆汇编命令段中可使用C语言的注释语句。如果有多条汇编指令嵌入,则可用“{}”将它们归为一条语句,注意1.内嵌汇编--内嵌汇编注意事项对于寄存器R0~R3、LR和PC的使用要格外小心。编译器在计算表达式时可能会将寄存器R0~

R3、R12和R14用于子程序调用,因此在内嵌的汇编指令中,不要将这些寄存器同时指定为物理寄存器。__asm{MOVR0,xADDy,R0,x/y/*(x/y)的结果覆盖了R0*/}例:1.内嵌汇编--内嵌汇编注意事项不要使用寄存器寻址变量

。intbad_f(intx){__asm{ADDR0,R0,#1}/*将发生寄存器冲突,R0中保存的x的值将不变*/returnx;}例:1.内嵌汇编--内嵌汇编注意事项使用内嵌汇编时,编译器会自动保存和恢复可能用到的寄存器,用户无须在程序中再作这些工作。读物理寄

存器(除PSR寄存器之外)之前必须先进行写入。intf(intx){__asm{STMFDSP,{R0};由于SP出现了写前先读,因此对R0的保存是非法的ADDR0,x,#1EORx,R0,xLDMFDSP!,{R0};对R0的恢复没有必要}returnx;}例

:1.内嵌汇编--内嵌汇编注意事项LDM和STM指令的寄存器列表中只允许使用物理寄存器。内嵌汇编可以修改处理器模式、协处理器状态和FP、SL、SB等ATPCS寄存器,但是编译器在编译时并不了解这些变化,所以必须保证在执行C语言代码前

恢复被改变了的处理器模式。由于汇编语言使用“,”作为操作数的分隔符,因此带“,”的C语言表达式作为操作数时,必须用“()”括起来归为一个汇编操作数。#include<stdio.h>voiddo_strcpy(constchar*sr

c,char*dest){//字符串复制函数charch;__asm//注:本章节所有示例中均默认CPU是ARM状态,实际应用中可能需要加以判断。{loop:ldrbch,[src],#1//读取下一

个字符strbch,[dest],#1//存储下一个字符cmpch,#0//检查文本终点bneloop//若非终点转移到loop}}例4.4字符串复制__inlinevoidenable_IRQ(void){inttmp;__asm{MRStmp,CPS

RBICtmp,tmp,#0x80MSRCPSR_c,tmp}}__inlinevoiddisable_IRQ(void){inttmp;__asm{MRStmp,CPSRORRtmp,tmp,#0x8

0MSRCPSR_c,tmp}}例、使能和禁止中断intmain(void){disable_IRQ();enable_IRQ();}2.在汇编中使用C定义的全局变量内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文

件中,这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量【例4-5】在汇编中使用C定义的全局变量//C程序#include<stdio.h>intpubvar=5;//C定义的全局变量externasmdata(vo

id);intmain(){printf("oldvalueofpubvaris:%d",pubvar);asmdata();printf("newvalueofpubvaris:%d",pubvar);return0;};汇编程序AR

EAasmfunc,CODE,READONLYEXPORTasmdataIMPORTpubvarasmdataldrr0,=pubvar;r0←pub地址ldrr1,[r0];r1←[r0]movr2,#3;r2←#3mulr3,r1

,r2;r3←r1*r2strr3,[r0];[r0]←r3movpc,lr;从子程序返回END【例4-6】在C中调用汇编的函数(函数不多于4个参数);汇编程序AREAasmfunc,CODE,READONLYEXPORTdo_strcpy

do_strcpyloopldrbr4,[r0],#1;r4←[r0],r0r0+1cmpr4,#0;检查文本终点beqover;若终点转移到overstrbr4,[r1],#1;[r1]←r4,r1←r1+1bloopovermo

vpc,lr;从子程序返回END//C程序#include<stdio.h>externvoiddo_strcpy(constchar*src,char*dest);intmain(){constch

ar*s="myteststring!";chard[128];do_strcpy(s,d);printf("old:%s\r\n",s);printf("new:%s\r\n",d);return0;}【例4-7】在C中调用汇编的函数(函数多于4个参数);汇编程序:AREAaddcode,

CODE,READONLY;段addcode,代码段code32;ARM指令EXPORTmyadd_sixmyadd_sixstmfdr13,{r4,r5};将r4,r5压入堆栈,但R13不变ldrr4,[r13];将第5个参数从堆栈中提出ldrr5,[r13,#

4];将第6个参数从堆栈中提出addr0,r0,r1addr0,r0,r2addr0,r0,r3addr0,r0,r4addr0,r0,r5;32位结果保存在R0中subr13,r13,#8ldmfd

r13,{r4,r5};从堆栈中恢复r4,r5movr15,r14;返回主程序//C主程序#defineUINTunsignedintexternUINTmyadd_six(UINTa,UINTb,UINT

c,UINTd,UINTe,UINTf);intmain(void){myadd_six(1,2,3,4,5,6);return0;}4.在汇编中调用C的函数在汇编语言中调用C语言的函数,需要在汇编中IMPORT对应的C函数名,然后将C

的代码放在一个独立的C文件中进行编译,剩下的工作由连接器来处理。【例4-8】在汇编语言中调用C语言的函数(参数不多于4个)。//C函数prog1_c.cvoidprog1_c(intp1,intp2,

intp3){printk("%0x%0x%0x\r\n",p1,p2,p3);//输出参数值};汇编程序prog1_asm.sIMPORTprog1_c;声明prog1_c函数AREAPROG1_AS

M,CODE,READONLYprog1_asmSTRlr,[sp,#-4]!;保存当前lrldrr0,=0x1;参数1ldrr1,=0x2;参数2ldrr2,=0x3;参数3blprog1_c;调用C函数LDRpc,[sp],#4;将lr装进pc(返回main函数)END

【例4-9】在汇编语言中调用C语言的函数(参数多于4个)。//C函数prog2_c.cvoidprog2_c(intp1,intp2,intp3,intp4,intp5,intp6){printk("%0x%0x%0x%0x%0x%0x\r

\n",p1,p2,p3,p4,p5,p6);//输出参数值};汇编程序prog2_asm.sIMPORTprog2_c;声明prog2_c函数AREAPROG2_ASM,CODE,READONLYEXPORTprog2_a

smprog2_asmSTRlr,[sp,#-4]!;保存当前lrldrr0,=0x1;参数1ldrr1,=0x2;参数2ldrr2,=0x3;参数3ldrr3,=0x4;参数4ldrr4,=0x6strr4,[sp,

#-4]!;参数6入栈ldrr4,=0x5strr4,[sp,#-4]!;参数5入栈blprog2_cADDsp,sp,#4;清除栈中参数5,本语句执行完后sp指向参数6ADDsp,sp,#4;清除栈中

参数6,本语句执行完后sp指向lrLDRpc,[sp],#4;将lr装进pc(返回main函数)END4.5ARM汇编语言实验基础4.5.1ADS软件组成4.5.2使用CodeWarriorIDE4.5.3使用AXDIDEADS全称为

ARMDeveloperSuite,是ARM公司推出的新一代ARM集成开发工具。现在常用的ADS版本是ADS1.2,它取代了早期的ADS1.1和ADS1.0。ADS用于无操作系统的ARM系统开发,是对裸机(可理解成一个高级单片机)的开发。ADS有极佳的测试

环境和良好的侦错功能,它可使硬件开发者更深入地从底层去理解ARM处理器的工作原理和操作方法,为日后自行设计打基础,为BootLoader的编写和调试打基础。4.5.1ADS集成开发环境简介1.命令行开发工具命令行开发工具在实际应用中相对来说

比较广泛,使用它的好处在于可以将许多编译命令写在一个脚本文件中,然后只执行该脚本文件就可以让工具自动完成所有编译、链接工作生成可执行代码。命令行开发工具中常用的命令如下。(1)armccarmcc是ARMC编译器,用于将用ANSIC编写的程序编译

成32位的ARM指令代码。armcc命令使用时可附带参数。在命令控制台环境下,输入以下命令:>armcc–help将可以查看armcc的语法格式以及最常用的一些操作选项。armcc的基本语法格式为>armcc[options]file1file2…filen4.5.1ADS软件组成(2)armcp

parmcpp是ARMC++编译器,它将ISOC++或EC++编译成32位的ARM指令代码。该编译器的命令选项和armcc的选项基本一样,这里不再重复。(3)tcctcc是ThumbC编译器,它将ANSIC源代码编译成16位的Thum

b指令代码。tcc的编译选项和用法类似armcc,具体使用请参考ADS软件的在线帮助文件。(4)tcpptcpp是ThumbC++编译器,它将ISOC++和EC++源码编译成16位Thumb指令代码。它的编译选项和用法类似armcc,具体使用请参考ADS软件的在线帮助文件。4.5.1AD

S软件组成(5)armasmarmasm是ARM和Thumb的汇编器,它对用ARM汇编语言和Thumb汇编语言写的源代码进行汇编。在命令行输入armasm–help将会看到armasm汇编器的用法以及它的编译选项。armasm的基本语法格式有两种:

>armasm[options]sourcefileobjectfile>armasm[options]-oobjectfilesourcefile4.5.1ADS软件组成ADS软件组成(6)armlinkarmlink是ARM链接器,该命令既可以将编译得到的一个或多个目标文件和相关的一个或

多个库文件进行链接,生成一个可执行文件,也可以将多个目标文件部分链接成一个目标文件,以供进一步地链接。ARM链接器生成的是ELF格式的可执行映像文件。armlink的语法格式如下:>armlinkoption-listinput-file-l

ist(7)armsdarmsd是ARM和Thumb的符号调试器,它能够进行源码级的程序调试。用户可以在用C或汇编语言写的代码中进行单步调试,设置断点,查看变量值和内存单元的内容。armsd的语法格式如下:>armsd[options

][<imagefile>[<arguments>]]2.ARM运行时库ADS提供两种运行时库来支持C和C++代码的编译,一种是ANSIC库函数,另一种是C++库函数。ANSIC库函数包含在ISOC标准中定义的函数以及被C和C++编译器所调用的

支持函数。C++库函数包含由ISOC++标准定义的函数。3.GUI开发环境ADSGUI开发环境包含CodeWarrior和AXD两种,其中CodeWarrior是集成开发工具,而AXD是调试工具。CodeWarriorforARM是一套完整的集成开发工具,充分发挥了ARMRIS

C的优势,使产品开发人员能够很好的应用尖端的片上系统技术。该工具是专为基于ARMRISC的处理器而设计的,它可加速并简化嵌入式开发过程中的每一个环节,使得开发人员只须通过一个集成软件开发环境就能研制出ARM产品。AXD(ARMeXtendedDeb

ugger)即ARM扩展调试器。调试器本身是一个软件,用户通过这个软件使用调试代理可以对包含有调试信息的、正在运行的可执行代码进行变量的查看、断点的控制等调试操作。ADS软件组成4.实用程序ADS除了

提供上述工具外,它还提供以下的实用工具来配合前面介绍的命令行开发工具的使用。(1)FlashdownloaderFlashdownloader是用于把二进制映像文件下载到ARM开发板上的Flash存储器的工具。(2)fromELFfromELF是A

RM映像文件转换工具。该命令将ELF格式的文件作为输入文件,将该格式转换为各种输出格式的文件,包括plainbinary(BIN格式映像文件)、Motorola32-bitS-recordformat(Motorola32位S格式

映像文件)、IntelHex32format(Intel32位格式映像文件)和Verilog-likehexformat(Verilog十六进制文件)。fromELF命令也能够为输入映像文件产生文本信息,如代码和数据长度。(3)armarARM库函数生

成器将一系列ELF格式的目标文件以库函数的形式集合在一起,用户可以把一个库传递给一个链接器以代替几个ELF文件。ADS软件组成5.支持软件仿真ADS为用户提供ARMulator软件,使用户可以在软件仿真

的环境下或者在基于ARM的硬件环境下调试用户的应用程序。ARMulator是一个ARM指令集仿真器,集成在ARM的调试器AXD中,它提供对ARM处理器的指令集的仿真,为ARM和Thumb提供精确的模拟。用户可以在硬件尚未做好的情况下,开发程序代码。ADS软件主要由上述5个部

分组成,下面将介绍在实际开发中使用频繁的CodeWarrior和AXD工具的基本使用。ADS软件组成1.创建项目工程建立项目工程是嵌入式开发的第1步,因为工程将所有的源代码文件组织在一起,并能够决定最终生成文件存放的路径、输出的格式等。运行ADS1.2开发软件(Cod

eWarriorforARMDeveloperSuite),打开CodeWarrior集成开发环境,如图7-1所示。在CodeWarrior中新建一个工程的方法有两种,可以在工具栏中单击New按钮,也可以在File菜单中选择New命令,如图7-1所示,这样就会打开一个如图7-2所示的新建

工程对话框。在Project列表框中有7种可选择的工程类型。●ARMExecutableImage:用于将ARM指令代码生成一个ELF格式的可执行映像文件;●ARMObjectLibrary:用

于将ARM指令代码生成一个armar格式的目标文件库;●EmptyProject:用于创建一个不包含任何库或源文件的工程;●MakefileImporterWizard:用于将VisualC的nmake或GNUmake文件转换成C

odeWarriorIDE工程文件;4.5.2使用CodeWarriorIDE●ThumbARMInterworkingImage:用于将ARM指令和Thumb指令的混和代码生成一个可执行的ELF格式的映像文件;●ThumbExecutableI

mage:用于将Thumb指令代码生成可执行的ELF格式的映像文件;●ThumbObjectLibrary:用于将Thumb指令的代码生成一个armar格式的目标文件库。4.5.2使用CodeWarriorIDE4.5.2使用CodeWarriorIDE2.编译和链接项目工程在编译casmt

est项目之前,要先进行目标生成选项的设置工作,这些选项包括编译器选项、汇编选项、链接器选项等,它们将决定CodeWarriorIDE如何处理工程项目,并生成特定的输出文件。单击Edit菜单,选择DebugRelSettings

命令,或者按Alt+F7组合键,显示如图7-10所示的对话框。图7-10的最左边部分是目标设置面板,它包括以下几个大的设置选项。(1)Target设置选项●TargetSettings:包括TargetNa

me、Linker、Pre-linker、Post-linker等设置;●AccessPaths:主要用于项目的路径设置;●BuildExtras:主要用于Build附加的选项设置;●RuntimeSetti

ngs:包括一般设置、环境设置等;●FileMappings:包含映射信息、文件类型、编辑语言等;●SourceTrees:包含源代码树结构信息以及路径选择等;●ARMTarget:定义输出image文件名、类型等。(2)LanguageSettings设置选项●ARM

Assembler:对ARM汇编语言的支持选项设置;●ARMCCompiler:对C语言的支持选项设置;●ARMC++Compiler:对C++语言的支持选项设置;●ThumbCCompiler:对ThumbC语言的支

持选项设置;●ThumbC++Compiler:对ThumbC++语言的支持选项设置。4.5.2使用CodeWarriorIDE(3)Linker设置选项●ARMLinker:对输出的链接类型、ROBase、RWBase地址等选项设置;●ARMfromELF:定

义输出文件格式以及路径等。(4)Editor设置选项●CustomKeywords:对客户关键字高亮颜色的设置。(5)Debugger设置选项●OtherExecutables:当调试该目标板时制定其他的可执行文件来调

试;●DebuggerSettings:对调试器的一些基本设置;●ARMDebugger:选择调试时的调试器(AXD、Armsd或其他调试器);●ARMRunner:选择运行时的调试器(AXD、Armsd或其他调试器)。

(6)Miscellaneous设置选项●ARMFeatures:设置一些受限制的特性。4.5.2使用CodeWarriorIDEAXD是ADS软件中独立于CodeWarriorIDE的图形软件。1.打开调试文件2.设置断点调试

时,用户往往希望在程序执行到某处时查看所关心的变量值,此时可以通过设置断点达到要求。将光标移动到要进行断点设置的代码处,在Execute菜单中,选择ToggleBreakpoint命令或按F9键,就会在光标所在行的起始位置出现一个红色实心圆点,表明该处已设为断点。假

设本例中给第8行代码设置断点,首先将光标移至第8行,然后按F9键或单击ToggleBreakpoint按钮。3.查看寄存器和存储器的内容查看寄存器或存储器的值在实际开发调试中经常使用。使用方法为从Pro

cessorViews菜单中选择Registers命令可观察寄存器的内容。4.查看变量值在调试过程中,经常需要查看某个变量的值。在AXD工具中,查看变量值的方法是先用鼠标选中要查看的变量,然后右击,在

弹出的快捷菜单中选择Watch命令,将会显示指定变量的详细信息。此处以6行的c为要查看的变量为例,先选中c变量,然后右击,选择Watch命令,将弹出如图7-24所示的对话框,该对话框显示了c变量的地址、数值等详细信息。4.5.3使用AXDIDE

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?