【文档说明】第四章ARM系统硬件设计基础课件.ppt,共(58)页,263.512 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-92626.html
以下为本文档部分文字说明:
第4章ARM系统硬件设计基础1、汇编语言程序常用的符号(1)常量常量是指其值在程序运行过程中不能被改变的量。ARM汇编程序支持的常量有数字常量、逻辑常量和字符串常量。数字常量一般为32位的整数;逻辑常量只有两种取值:真或假;字符串常量为一个固定的字
符串。(2)变量变量是指其值在程序运行过程中可以改变的量。在ARM汇编语言程序中,可使用GBLA、GBLL、GBLS伪指令声明全局变量,使用LCLA、LCLL、LCLS伪指令声明局部变量,并可使用SETA、SETL和SE
TS对其进行初始化。(3)变量代换程序中的变量可通过代换操作取得一个常量。代换操作符为“$”。数字变量前面有一个代换操作符“$”,编译器会将该数字变量的值转换为十六进制的字符串,并将该十六进制的字符串代换“
$”后的数字变量。逻辑变量前面有一个代换操作符“$”,编译器会将该逻辑变量代换为它的取值(真或假)。字符串变量前面有一个代换操作符“$”,编译器会将该字符串变量的值代换“$”后的字符串变量。(3)变量代换LCLSS1;定义局部字符串变
量S1和S2LCLSS2S1SETS“Test!”S2SETS“Thisisa$S1”;字符串变量S2的值为“ThisisaTest!”4.2.1ARM汇编器支持的伪指令伪操作不像机器指令一样在CPU运行时执行,而是在汇编程序期间进行处理的。1、符号定义(SymbolDefinition)伪
操作2、数据定义(DataDefinition)伪操作3、汇编控制(AssemblyControl)伪操作4、其他常用的伪操作1、符号定义伪操作符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义
寄存器的别名等操作。常见的符号定义伪指令有如下几种:(1)定义全局变量GBLA、GBLL和GBLS(2)定义局部变量LCLA、LCLL和LCLS(3)对变量赋值SETA、SETL、SETS(1)GBLA、GBLL和G
BLS语法GBLA(GBLL或GBLS)全局变量名GBLA(GlobalArithmetic)定义一个全局的数字变量,并初始化为0GBLL(GlobalLogic)定义一个全局的逻辑变量,并初始化为F(假)GBLS(G
lobalString)定义一个全局的字符串变量,并初始化为空(1)GBLA、GBLL和GBLSGBLATest1Test1SETA0xaaGBLLTest2Test2SETL{TRUE}GBLSTest3Test3SETS“Testing”(2)L
CLA、LCLL和LCLS语法格式LCLA(LCLL或LCLS)局部变量名LCLA伪指令用于定义一个局部的数字变量,并初始化为0LCLL伪指令用于定义一个局部的逻辑变量,并初始化为F(假)LCLS伪指令
用于定义一个局部的字符串变量,并初始化为空(2)LCLA、LCLL和LCLSLCLATest4Test1SETA0xaaLCLLTest5Test2SETL{TRUE}LCLSTest6Test3SETS“Testing”(3)SETA、SET
L和SETS语法变量名SETA(SETL或SETS)表达式SETA伪指令用于给一个数字变量赋值SETL伪指令用于给一个逻辑变量赋值SETS伪指令用于给一个字符串变量赋值(4)RLIST(RegisterList)语法名称RLIST{寄存器列表}作
用对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在ARM指令LDM/STM中使用实例RegListRLIST{R0-R5,R8,R10}2、数据定义伪操作数据定义伪操作一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初
始化。(1)DCB(DistributeContinuousByte)语法标号DCB表达式作用分配一片连续的字节存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为0~255的数字或字符串。DCB也可用“=”代替。实例StrDCB“Thisisatest!”(2)DC
W语法标号DCW表达式作用分配一片连续的半字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。实例DataTestDCW1,2,3(3)DCD语法标号DCD表达式
作用分配一片连续的字存储单元并用伪指令中指定的表达式初始化。其中,表达式可以为程序标号或数字表达式。DCD也可用“&”代替。实例DataTestDCD4,5,6(4)DCFD语法标号DCFD表达
式作用为双精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个双精度的浮点数占据两个字单元。实例FDataTestDCFD2E115,-5E7(5)DCFS语法标号DCFS表达式作用
为单精度的浮点数分配一片连续的字存储单元并用伪指令中指定的表达式初始化。每个单精度的浮点数占据一个字单元。实例FDataTestDCFS2E5,-5E-7(6)DCQ语法标号DCQ表达式作用分配一片以8个字
节为单位的连续存储区域并用伪指令中指定的表达式初始化。实例DataTestDCQ100(7)SPACE语法标号SPACE表达式作用分配一片连续的存储区域并初始化为0。其中,表达式为要分配的字节数。SPACE也可
用“%”代替。实例DataTestSPACE100(8)MAP语法MAP表达式{,基址寄存器}作用定义一个结构化的内存表的首地址。MAP也可用“^”代替。表达式可以为标号或数学表达式,当基址寄存器选项不存在时,表达式的值即为内存表的首地址;当该选项存在时,内存表的
首地址为表达式的值与基址寄存器的和。实例MAP0x100,R0(9)FIELD语法标号FIELD表达式作用定义一个结构化内存表中的数据域。FILED也可用“#”代替。表达式的值为当前数据域在内存表中所占的字节数。实例MAP0x100AFIELD16BFIELD32SFIELD256
4、其他常用的伪指令AREAALIGNENTRYENDEQUEXPORT(或GLOBAL)IMPORTEXTERNGET(或INCLUDE)INCBIN(1)AREA语法AREA段名属性1,属性2,……作用用于定义一个代码段或数据段。
段名若以数字开头,则该段名需用“|”括起来,如|1_test|。属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。(1)AREA常用的属性如下:CODE定义代码段DATA定义数据段READONLY指定本段
为只读,代码段默认为READONLYREADWRITE指定本段为可读可写,数据段的默认为READWRITE(1)AREACOMMON定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。实例AREAInit,CODE,READONLY(2)ALIGN
语法ALIGN{表达式{,偏移量}}作用通过添加填充字节的方式,使当前位置满足一定的对齐方式。其中,表达式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个
数字表达式,若使用该字段,则当前位置的对齐方式为:2的表达式次幂+偏移量。实例AREAInit,CODE,READONLY,ALIGN=3(3)ENTRY语法ENTRY作用指定汇编程序的入口点实例AREAInit,CODE,READONLYENTR
Y……(4)END语法END作用通知编译器已经到了源程序的结尾实例AREAInit,CODE,READONLY……END(5)EQU语法名称EQU表达式{,类型}作用为程序中的常量、标号等定义一个等效的字符名称。其中EQU可用“*”代替。名称为EQU伪指令定义的字符名称。实例Tes
tEQU50(6)EXPORT(或GLOBAL)语法EXPORT标号作用声明一个全局的标号,该标号可在其他的文件中引用。标号在程序中区分大小写。实例AREAInit,CODE,READONLYEXPORTStest(7)IMPORT语法IMPORT标号作用通知编译器要使
用的标号在其他的源文件中定义,但要在当前源文件中引用。而且无论当前源文件是否引用该标号,该标号均会被加入到当前源文件的符号表中。实例AREAInit,CODE,READONLYIMPORTmain(8)EXTERN语法EXTERN标号
作用通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,如果当前源文件实际并未引用该标号,该标号就不会被加入到当前源文件的符号表中。实例AREAInit,CODE,READONLYEXTERNmain(9)GET语法GET文件名作用将一个源文件包含到当前的
源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET。实例AREAInit,CODE,READONLYGETa1.sGETC:\a2.s(10)INCBIN语法INC
BIN文件名作用将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放在当前文件中,编译器从其后开始继续处理。实例AREAInit,CODE,READONLYINCBINa1.datINCBINC:\a2.txt(11)RN语法名称RN表达式作用给一
个寄存器定义一个别名。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。实例TempRNR0(12)ROUT语法{名称}ROUT作用给一个局部变量定义作用范围。在程序中未使用该伪指令时,局部变量的作用范围为所在的AREA
,而使用ROUT后,局部变量的作为范围为当前ROUT和下一个ROUT之间。4.2.2基于ARM的汇编语言程序设计ARM汇编语言的语句格式为:{标号}{指令或伪指令}{;注释}每条指令的助记符可以全部用大写、或全部用小写,但不允许在
一条指令中大、小写混用。如果一条语句太长,可分为若干行,在行尾用续行符“\”。汇编语言的语句格式1、标号是代表地址的符号,必须在一行的顶格书写,其后不能添加冒号“:”。2、程序中所有指令均不能顶格书写。3、在ARM汇编语言中,ARM指令、伪指令、寄存器名等
可以全部大写或者全部小写,但不能大小写混合使用。4.2.3ARM汇编语言程序的基本结构在ARM汇编程序中,以程序段为单位组织代码。段是相对独立的指令或数据序列,具有特定的名称。段可以分为代码段和数据段,代码段的内容为执行代码,数据段存放代码运行时需要用到的
数据。一个汇编程序至少应该有一个代码段,当程序较长时,可以分割为多个代码段和数据段,多个段在程序编译链接时最终形成一个可执行的映象文件。AREAInit,CODE,READONLYENTRYStartLDRR0,=0x3FF5
000LDRR1,=0xFFSTRR1,[R0]LDRR0,=0x3FF5008LDRR1,=0x01STRR1,[R0]......END在汇编语言程序中,用AREA伪指令定义一个段,并说明所定义段的相关属性,本例定义一个名为Init的代码段,属性为只读。ENTRY伪指令标识程序的入口点,接
下来为指令序列。程序的末尾为END伪指令,该伪指令告诉编译器源文件的结束,每一个汇编程序段都必须有一条END伪指令,指示代码段的结束。汇编语言的子程序调用在ARM汇编语言程序中,子程序的调用一般是通过BL指令来实现的。BL子程序名汇编语言的
子程序调用该指令在执行时完成如下操作:将子程序的返回地址存放在连接寄存器LR中,同时将程序计数器PC指向子程序的入口点。当子程序执行完毕需要返回调用处时,只需要将存放在LR中的返回地址重新拷贝给程序计数器PC即可。在调用
子程序的同时,也可以完成参数的传递和从子程序返回运算的结果,通常可以使用寄存器R0~R3完成。AREAInit,CODE,READONLYENTRYStartLDRR0,=0x3FF5000LDRR1,=0xFFSTRR1,
[R0]LDRR0,=0x3FF5008LDRR1,=0x01STRR1,[R0]BLPRINT_TEXT......PRINT_TEXT......MOVPC,LR......END一个数据段的例子AREAData
Area,DATA,NOINIT,ALIGN=2DISPBUFSPACE200RCVBUFSPACE200…其中DATA为数据段的标识。4.2.4基于ARM的汇编语言程序举例以下是一个基于S3C2410的LED点灯程序。;LED点灯实验;端口F寄存器预定义rGPFCONEQ
U0x56000050rGPFDATEQU0x56000054rGPFUPEQU0x56000058AREAInit,CODE,READONLYENTRYResetEntryldrr0,=rGPFCON
ldrr1,=0x4000;设置I/O口GPF7为输出属性strr1,[r0]ldrr0,=rGPFUPldrr1,=0xff;禁止GPF端口的上拉电阻strr1,[r0]ldrr2,=rGPFDATledloopldrr1,=0x80strr1,[r2];使GPF7输出
高电平,D14灯亮bldelay;调用延迟子程序ldrr1,=0x00strr1,[r2];使GPF7输出低电平,D14灯灭bldelay;调用延迟bledloop;不断的循环,D14将不停的闪烁;下面是延迟子程序delayldrr3,=0x1ffff;
设置延迟的时间delay1subr3,r3,#1;r3=r3-1cmpr3,#0x0;将r3的值与0相比较bnedelay1;比较的结果不为0,继续调用delay1,否则执行下一条语句movpc,lr;返回END4.4基于ARM的C语言与汇编语
言混合编程汇编语言与C/C++的混合编程通常有以下几种方式:-在C/C++代码中嵌入汇编指令-在汇编程序和C/C++的程序之间进行变量的互访-汇编程序、C/C++程序间的相互调用在实际的编程应用中,使用较多的方
式是:程序的初始化部分用汇编语言完成,然后用C/C++完成主要的编程任务,程序在执行时首先完成初始化过程,然后跳转到C/C++程序代码中。4.4.1C语言与汇编语言混合编程应遵守的规则在C程序和ARM汇
编程序之间相互调用时必须遵守ATPCS规则。ATPCS规定了一些子程序间调用的基本规则,比如:寄存器的使用规则子程序之间通过寄存器r0~r3来传递参数,当参数个数多于4个时,使用堆栈来传递参数。在子程序中
,使用寄存器r4~r11保存局部变量。寄存器r12用于保存堆栈指针SP,当子程序返回时使用该寄存器出栈,记作IP。寄存器r13用作堆栈指针,记作SP。寄存器r14称为链接寄存器,记作LR。该寄存器用于
保存子程序的返回地址。寄存器r15称为程序计数器,记作PC。4.4.1C语言与汇编语言混合编程应遵守的规则在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规则。ATPCS规定了一些子程序间调用的基本规则,比如:堆栈的使用规则堆栈采用满递减类型(FD
,FullDescending),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。参数的传递规则整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一
组连续的FP寄存器传递参数子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。结果为浮点数时,通过浮点运算部件的寄存器F0、D0或S0返回4.4.2汇编程序调用C程序的方法汇编
程序调用C程序的方法为:首先在汇编程序中使用IMPORT伪指令事先声明将要调用的C语言函数;然后通过BL指令来调用C函数。例如在一个C源文件中定义了如下求和函数:intadd(intx,inty){return(x+y);}调用add()函数的汇编程序结构如下
:IMPORTadd;声明要调用的C函数…MOVr0,1MOVr1,2BLadd;调用C函数add4.4.3C程序调用汇编程序的方法C程序调用汇编子程序的方法为:首先在汇编程序中使用EXPORT伪指令声明被调用的子程序,表示该子程序将在其他文件中被调用;然后在C程序中使用extern关键字声
明要调用的汇编子程序为外部函数。例如在一个汇编源文件中定义了如下求和函数:EXPORTadd;声明add子程序将被外部函数调用…add;求和子程序addADDr0,r0,r1MOVpc,lr…在一个C程序的main()函数中对add汇编子程序进行了调用:exte
rnintadd(intx,inty);//声明add为外部函数voidmain(){inta=1,b=2,c;c=add(a,b);//调用add子程序…}4.4.4C程序中内嵌汇编语句在C语言中内嵌汇编语句可以实现一些高级语言不能实现或者高级语言不容易实现
的功能以及时间紧迫的功能。内嵌的汇编器支持大部分ARM指令和Thumb指令,但是不支持诸如直接修改PC实现跳转的底层功能,也不能直接引用C语言中的变量。嵌入式汇编语句在形式上表现为独立定义的函数体,其语法格式
为:__asm{指令[;指令]…[指令]}