五、汇编程序设计.ppt_第1页
五、汇编程序设计.ppt_第2页
五、汇编程序设计.ppt_第3页
五、汇编程序设计.ppt_第4页
五、汇编程序设计.ppt_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

1、第五章汇编程序设计,本章目标,掌握汇编程序的构成 掌握规范的汇编编程 掌握常用汇编伪指令 掌握C程序内嵌汇编编程方法 掌握汇编语言调用C程序 掌握C语言调用汇编程序,常用ARM源程序文件类型,汇编程序结构,汇编程序结构,汇编程序构成,ARM的汇编语言程序一般由几个段组成,每个段均由AREA伪操作定义。 段可以分为多种,如代码段、数据段、通用段,每个段又有不同的属性,如代码段的默认属性为READONLY,数据段的默认属性为READWRITE。 本程序定义了两个段,第一个段为代码段codesec,它在存储器中存放用于程序执行的代码以及main函数的本地字符串;第二个段为数据段constdatase

2、c,存放了全局的字符串,由于本程序没有对数据进行写操作,该数据段定义属性为READONLY。,汇编程序构成,格式: 标签 指令/伪操作/伪指令 操作数 ;语句的注释 所有的标签必须在一行的开头顶格写,前面不能留空格,后面也不能跟C语言中的标签一样加上“:”; ARM汇编器对标识符的大小写敏感,书写标号及指令时字母的大小写要一致; 注释使用“;”符号,注释的内容从“;”开始到该行的结尾结束。,汇编程序构成,标签 标签是一个符号,可以代表指令的地址、变量、数据的地址和常量。 一般以字母开头,由字母、数字、下划线组成。 当符号代表地址时又称标号,可以以数字开头,其作用范围为当前段或者在下一个ROUT

3、伪操作之前。 指令/伪操作 指令/伪操作是指令的助记符或者定义符,它告诉ARM的处理器应该执行什么样的操作或者告诉汇编程序伪指令语句的伪操作功能。,汇编程序标号,标号代表地址。 标号分为段内标号和段外标号。段内标号的地址值在汇编时确定,段外编号的地址值在链接时确定 。 在程序段中,标号代表其所在位置与段首地址的偏移量。根据程序计数器(PC)和偏移量计算地址即程序相对寻址。 在映像中定义的标号代表标号到映像首地址的偏移量。映像的首地址通常被赋予一个寄存器,根据该寄存器值与偏移量计算地址即寄存器相对寻址。 例如: loop SUBS r0,r0,#1;每次循环使r0=r0-1 BNE loop;跳

4、转到loop 标号去执行,汇编程序标号,在宏中也可以使用局部符号。 局部标号是099的十进位数开始,可以重复定义。 局部标号引用格式: F|BA|T Nroutname %:局部标号引用操作。 F:编译器只向前搜索。 B:编译器只向后搜索。 A:编译器搜索宏的所有嵌套层次。 T:编译器搜索宏的当前层。 例如: 01 SUBS r0,r0,#1 ;每次循环使r0=r0-1 BNE %B01;跳转到01标号去执行,伪指令,在ARM汇编语言源程序中有些特殊助记符,它们没有相对应的操作码或者机器码,通常称为伪指令,它们所完成的操作称为伪操作。 伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,由

5、汇编程序在源程序的汇编期间进行处理,仅在汇编过程中起作用。 在ARM的汇编程序中,有如下几种伪指令: 符号定义伪指令 数据定义伪指令 汇编控制伪指令 信息报告伪指令 宏指令以及其他伪指令,符号定义伪指令,作用: 用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等。 符号定义有如下几种伪指令: 用于定义局部变量的LCLA、LCLL和LCLS。 用于定义全局变量的GBLA、GBLL和GBLS。 用于对变量赋值的SETA、SETL和SETS。 为通用寄存器列表定义名称的RLIST。,其中: xxLA定义一个数字变量,初始化为0。 xxLL定义一个逻辑变量,初始化为F。 xxLS定义一个

6、字符串变量,初始化为空串。,数据定义伪指令,作用:为数据分配存储单元,同时初始化。 有如下几种: DCB 字节分配 DCW/DCWU 半字(2字节)分配 DCD/DCDU 字(4字节)分配 DCQ/DCQU 8个字节分配 DCFS/DCFSU 单精度浮点数分配 DCFD/DCFDU 双精度浮点数分配 SPACE 分配一块连续的存储单元 FIELD 定义一个结构化的内存表的数据域 MAP 定义一个结构化的内存表首地址,例如: Arrayd1 DCD 1334,234,345435 ;构造固定数组并分配字为单元的存储单元 LabelDCDstr1;该字单元存放str1的地址,其它伪指令,在汇编程序

7、中经常会使用一些其他的伪指令,包括以下18条: ASSERTAREA ALIGN CODE16/CODE32 ENTRYEND EQU IMPORT EXPORT/GLOBAL EXTERN INCBINGET/INCLUDE RNROUT ADR ADRL LDR NOP,其它伪指令,AREA 格式: AREA 段名属性, 说明:AREA用于定义一个代码段、数据段或者特定属性的段。如果段名以数字开头,那么该段名需用“|”字符括起来,如|7wolf|,用C的编译器产生的代码一般也用“|”括起来。属性部分表示该代码段/数据段的相关属性,多个属性可以用“,”分隔。 常见属性如下: DATA:定义数

8、据段,默认属性是READWRITE。 CODE:定义代码段,默认属性是READONLY 。 READONLY:表示本段为只读。 READWRITE:表示本段可读写。 ALIGN=表达式,表示段的对齐方式为2的表达式次方,例如:表达式=3,则对齐方式为8字节对齐。表达式的取值范围为031。,其它伪指令,EQU 格式: 名称 EQU表达式 ,类型 说明: EQU用于将程序中的数字常量、标号、基于寄存器的值赋予一个等效的名称,这一点类似于C语言中的define.可用“*”代替EQU。 如果表达式为32位的常量,我们可以指定表达式的数据类型,类型域可以有以下3种:CODE16/CODE32/DATA

9、例如: num1EQU1234;定义num1为1234 addr5EQUstr1+0 x50 d1EQU0 x2400,CODE32 ;定义d1的为0 x2400,且该处为32位的ARM指令,其它伪指令,EXPORT/GLOBAL 格式:EXPORT/GLOBAL标号 ,WEAK 说明: EXPORT在程序中声明一个全局标号,其他文件中的代码可以被该标号引用。用户也可以用GLOBAL代替EXPORT。 ,WEAK可选项声明其他文件有同名的标号,则该同名标号优先于该标号被引用。 IMPORT 格式:IMPORT标号 ,WEAK 说明: 告诉编译器,这个标号要在当前源文件中使用,但标号是在其他的源

10、文件中定义的。 ,WEAK:如果所有的源文件都没有找到这个标号的定义,编译器也不会提示错误信息,同时编译器也不会到当前没有被INCLUDE进来的库中去查找该符号。,其它伪指令,GET/INCLUDE 格式: GET文件名 说明:GET将一个源文件包含到当前的源文件中,并 将被包含的源文件在当前位置展开进行汇编处理。 INCLUDE和GET的作用是等效的。 使用方法: 在某源文件中定义一些宏指令,用MAP和FIELD定义结构化的数据类型,用EQU定义常量的符号名称,然后用GET/INCLUDE将这个源文件包含到其他的源文件中。 INCBIN 格式: INCBIN 文件名 说明:INCBIN将一个

11、数据文件或者目标文件包含到当前的源文件中,编译时被包含的文件不作任何变动地存放在当前文件中,编译器从后面开始继续处理。,19,针对汇编语言编程工作量大、可移植性差等问题,大部分编程都采用C语言进行,这是因为C语言具有开发周期短、移植性强、可读性强,管理方便等优点。 对于与硬件密切相关且对时间要求较高的代码,一般采用汇编语言编写。除此之外,其他代码均可用C语言编写。 若汇编代码较为简洁,则可使用直接在C语言中内嵌汇编的方法编程;否则要将汇编程序以文件的形式加入到项目中,按照过程调用标准ATPCS(ARM/Thumb Procedure Call Standard)的规定与C程序相互调用与访问。,

12、混合编程,ATPCS与AAPCS,过程调用标准ATPCS(ARM-Thumb Produce Call Standard)规定了子程序间相互调用的基本规则, ATPCS规定子程序调用过程中寄存器的使用规则、数据栈的使用规则及参数的传递规则。 2007年,ARM公司推出了新的过程调用标准AAPCS(ARM Architecture Produce Call Standard),它只是改进了原有的ATPCS的二进制代码的兼容性。,过程调用标准ATPCS与AAPCS,寄存器使用规则,(1)子程序间通过寄存器R0R3传递参数,寄存器R0R3可记作A1A4。被调用的子程序在返回前无须恢复寄存器R0R3的

13、内容。,(2)在子程序中,ARM状态下使用寄存器R4R11来保存局部变量,寄存器R4R11可记作V1V8;Thumb状态下只能使用R4R7来保存局部变量。,(3)寄存器R12用作子程序间调用时临时保存栈指针,函数返回时使用该寄存器进行出栈,记作IP;在子程序间的链接代码中常有这种使用规则。,堆栈使用规则,堆栈使用规则 ATPCS规定堆栈采用满递减(FD),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。并且对数据栈的操作时要求8字节对齐的。,(4)通用寄存器R13用作数据栈指针,记作SP。 (5)通用寄存器R14用作链接寄存器 ; (6)通用寄存器R15用作程序计数器

14、,记作PC 。,参数传递规则,子程序结果返回规则 (1)结果为一个32位的整数时,通过寄存器R0返回;结果为一个64位整数时,通过寄存器R0,R1返回。 (2)对于位数更多的结果,需要通过内存来传递。,参数传递规则 对于参数个数可变的子程序,当参数个数不超过4个时,可以使用寄存器R0R3来传递;当参数个数超过4个时,还可以使用数据栈进行参数传递。,内嵌汇编,(1)ARM开发工具编译环境下内嵌汇编语法格式,内嵌汇编,void my_strcpy(const char *src, char *dest) char ch; _asm loop: ldrb ch, src, #1 strb ch, d

15、est, #1 cmp ch, #0 bne loop ,int main() char *a = forget it and move on!; char b64; my_strcpy(a, b); printf(original: %s, a); printf(copyed: %s, b); return 0; ,内嵌汇编,内嵌汇编的局限性 在C中内嵌的汇编指令包含大部分的ARM和Thumb指令,不过其使用与汇编文件中的指令有些不同,存在一些限制,主要有下面几个方面: a. 不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令 b. 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物

16、理寄存器冲突 c. R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能将R0到 R3、R12及R14用于子程序调用,因此要避免直接使用这些物理寄存器 d. 一般不要直接指定物理寄存器,而让编译器进行分配,汇编使用全局变量,(2)在汇编中使用C定义的全局变量 内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文件中。这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量。,int gVar_1 = 12; extern asmDouble(void); int main() printf(original value

17、 of gVar_1 is: %d,gVar_1); asmDouble(); printf( modified value of gVar_1 is: %d, gVar_1); return 0; ,汇编使用全局变量,AREA asmfile, CODE, READONLY EXPORT asmDouble IMPORT gVar_1 asmDouble ldr r0, =gVar_1 ldr r1, r0 mov r2, #2 mul r3, r1, r2 str r3, r0 mov pc, lr END,汇编程序调用C程序,(3)汇编程序调用C程序 在ARM开发工具编译环境下,汇编程序中要使用IMPORT伪操作声明将要调用的C程序。,例: 在C源文件中定义函数: int add(intx,inty) return(x+y); 在汇编程序中调用add()函数: IMPORT add;声明要调用的C函数 MOVr0,1 MOVr1,2 BL

温馨提示

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

最新文档

评论

0/150

提交评论