《汇编语言程序设计》由会员分享,可在线阅读,更多相关《汇编语言程序设计(35页珍藏版)》请在金锄头文库上搜索。
1、1TM第7章汇编语言程序设计本章主要介绍ARM汇编语言程序设计规范,以及在汇编语言程序设计中所要注意的问题,最后以大量的实例说明汇编语言程序设计方法。2TM2内容提要7.1 ARM汇编语言源程序格式及规范7.2 ARM汇编语言程序设计实例解析3TM3常用ARM源程序文件类型文件类型扩展名汇编语言源文件.SC语言源文件.CC+源文件.cpp引入文件.INC头文件.h4TM4汇编语言程序的结构CODE32 ;32 位的ARM指令段 AREA codesec,CODE,READONLY ;代码段,名称为codesec,属性为只读main PROC ;函数mainSTMFD SP!,LR ;保存必要的
2、寄存器和返回地址 ADR R0,strhello ;取标签strhello代表的地址值BL _printf ;调用C运行时库的_printf函数 ;“Hello world!”字符串BL welcomefun ;恢复子函数welcomefunLDMFD SP!,PC ; 恢复寄存器值strhello ;strhello代表本地制服穿的地址DCB “Hello world!n0” ;定义一段字节空间ENDP ;函数main结束5TM5welcomefun ;子函数welcomefunSTMFD SP!,LR ;保存必要的寄存器和返回地址ADR R0,adrstrarm ;取标签adrstrarm
3、代表的地址值到R0中LDR R0,R0,#0 ;将Strarm的值放到R0中BL _printf ;调用C运行时库的_printf函数打印;“Welcome to ARM world!”字符串LDMFD SP!,PC ; 恢复寄存器值adrstrarm ;adrstrarm标签DCD strarm ;保存strarm的地址AREA constdatasec,DATA,READONLY,ALIGN=2 ;数据段,名称constdatasec;只读,字对齐StrarmDCB “Welcome to ARM world!n0” ;存放“Welcome to ARM world!”;字符串6TM6EX
4、PORT main ;导出main函数供外部调用;引入三个C运行时的库函数和ARM库IMPORT _mainIMPORT _printfIMPORT |lib$request$armlib|,WEAKEND ;程序结束7TM7nARM的汇编语言程序一般由几个段组成,每个段都由AREA 伪操作定义。n段可以分为多种,如代码段、数据段、通用段,每个段又有 不同的属性,如代码段的默认属性为READONLY,数据段 的默认属性为READWRITE。n本程序定义了两个段,第一个段为代码段codesec,在存储 器中存放用于程序执行的代码以及main函数的本地字符串 ;第二个段为数据段constdatas
5、ec,存放了全局的字符串 ,由于本程序没有对数据进行写操作,该段定义的属性为 READONLY。8TM8ARM汇编语言程序设计格式及规范nARM编译环境下进行汇编语言程序设计的格式n汇编语句中的符号规则 9TM9ARM编译环境下汇编语句格式nADS环境下ARM汇编语句格式如下:标签 指令/伪操作/伪指令 操作数 ;语句的注释n所有的标签必须在一行的开头顶格写,前面不留空格 。后面也不能跟C语言中的标签一样加“:”;nARM汇编器对标识符的大小写敏感,书写标号以及指令时字母的大小写要一致;n注释使用“;”符号,注释的内容从“;”开始到该行的结尾结束。10TM10nARM编译环境下汇编语句中符号规
6、则1.符号命名规则(1)符号由大小写字母、数字、下划线组成,且符号是区分 大小写的。(2)局部标号可以用数字开头,其他的标号不能。(3)符号在其作用范围内必须是唯一的。(4)程序中的符号不要与指令助记符或者伪操作同名。 11TM11n标签标签是一个符号,可以代表指令的地址、数据的地址、变 量。一般以字母开头,由字母、数字、下划线组成。当符号代表地址时又称标号,可以以数字开头,其作用范 围为当前段或者在下一个ROUT伪操作之前。n指令/伪操作指令/伪操作是指令的助记符,他告诉ARM的处理器应该执 行什么样的操作或者告诉汇编程序伪指令语句的伪操作功 能。 12TM12n标号代表地址 标号分为段内标
7、号和段外标号。段内标号的地址值在汇编时确定,段外 标号的地址值在连接是确定。 在程序段中,标号代表其所在位置与段首地址的偏移量。根据程序计数 器(PC)和偏移量计算地址及程序相对寻址。 在影像中定义的标号代表标号到映像首地址的偏移量。映像的首地址通 常被赋予一个寄存器,根据寄存器值域偏移量计算地址即寄存器相对寻 址。例如loop SUBS R0,R0,#1 ;每次循环使R0=R0-1BNE loop ;跳转到loop标号去执行13TM13n在宏中也可以使用局部标号。局部标号是0-99的十进制开始,可以重复定义n被引用的局部标号语法规则是:% FB AT n routnamen其中:n是局部标号
8、的数字号。routname是当前局部范围的名称。%表示引用操作。F指示汇编器只向前搜索。 B指示汇编器只向后搜索。A指示汇编器搜索宏的所有嵌套层次。T指示汇编器搜索宏的当前层次。n例如 01 SUBS R0,R0,#1 ; 每次循环使R0=R0-1BNE %B01 ;跳转到01标号去执行14TM142.常量:其值在程序运行过程种不能被改变的量(1)十进制数,如535、246。(2)十六进制数,如0x645、0xff00。(3)n_XXX, n表示n进制数,从29,XXX是具体的数字。例如:8_3777(4)字符常量用一对单引号括起来,包括一个单字符或者标准C中的转义 字符。例如A、n。(5)字
9、符串常量由一对双引号以及由它括住的一组字符串组成,包括标准 C中的转义字符。如“abcdn”。(6)逻辑常量TRUE,FALSE,注意带大括号。如果需要使用双引号”或字符$,则必须用”和$代替。 15TM153.变量:这里所说的变量,是相对于汇编程序的变量,是用于汇编程序进行处理的,但一旦编译到程序中,则不会改变,成为常量。(1)数字变量(2)字符串变量(3)逻辑变量16TM16n在字符串变量的前面有一个$字符,在汇编时编译器会将该 字符串变量的内容代替该串字符。n在数字变量前面右一个代换操作符“$”,编译器会将该数字 变量的值转换为十六进制的字符串,并用该十六进制的字符 串代换“$”后的数字
10、变量。n需要将“$”字符加入到字符串中,可以用“$”代替,此时编 译器将不再进行变量代换,而是把“$”看做一个“$”n在两个“|”之间的“$”将不进行变量的代换,但如果“|”在双引 号内,则将进行变量代换。n使用“.”来表示字符串中变量名的结束。17TM17例子:(1)GBLS string1GBLS DGBLA numnum SETA 0x11223344D SETS “ARM9TDMI”string1 SETS “ABC$D$num”汇编后得到什么?18TM18例子(2) GLBS string1GLBS string2string1 SETS ”AAA”string2 SETS “$st
11、ring1.BBCC”汇编后结果是什么?19TM1920TM20n4.字符串表达式操作n(1)取符串的长度LENn语法格式:n:LEN: An功能说明:返回字符串A的长度。21TM21n(2)CHRn语法格式:n:CHR: A n功能说明:将A(A为某一字符的ASCII值)转换为单个字符。22TM22n(3)STRn语法格式:n:STR: A n功能说明:将A(A为数字量或逻辑表达式)转换成字符串。23TM23n(4)LEFTn语法格式:nA :LEFT: B n功能说明:返回字符串A最左端B(B为返回长度)长度的字符串。24TM24n(5)RIGHTn返回一个字符串最右端一定长度的字符串:n
12、A :RIGHT: Bn功能说明:返回字符串A最右端B(B为返回长度)长度的字符串。25TM25n(6)CCn用于连接两个字符串,B串接到A串后面:nA :CC: B 26TM267.2 ARM汇编语言程序设计实例解析27TM27n链接器ld用于把多个目标文件合并为一个可 执行文件。汇编器as生成的目标文件都假定 从地址0开始,ld为其指定最终的地址。n链接器ld把目标文件中的每个section都作为一个整体,为其分配运行的地址 28TM287.3 ARM 汇编语汇编语 言程序设计规设计规 范n汇编语汇编语 言预预定义义的寄存器名称nARM汇编语汇编语 言程序设计规设计规 范29TM29汇编器
13、预定义的寄存器名称 30TM30求一个数的阶乘(64位结果)nMOVR8 , #20低32位初始化为20nMOVR9 , #0 高位初始化为0nSUBR0,R8,#1初始化计数器nLoopnMOVR1 , R9暂存高位值nUMULLR8 , R9 , R0 , R8R9:R8=R0*R8nMLAR9 , R1 , R0 , R9R9=R1*R0+R9nSUBSR0 , R0 , #1计数器递减nBNELoop计数器不为0继续循环31TM31在ARM集成开发环境下编程:nAREA Fctrl, CODE, READONLY ; 声明代码FctrlnENTRY ; 标识程序入口nCODE32 ; 声明32 位ARM 指令nnStopnBStopnEND;文件结束32TM32n例子:先对内存地址0x3000开始的100个字 内存单元填入0x100000010x10000064字数 据,然后将每个字单元进行64位累加结果保 存于R9:R8。(R9中存放高32位)33TM33nAREA FCTRL, CODE, READONLY ; 声明代码 FCTRLnENTRY ; 标识程序入口nCODE32 ; 声明32 位ARM 指令nSTARTnMOVR0,#0X3000;初始化寄存器nMOVR1,#0X10000001nM