ARM指令及汇编程序设计.ppt
ARM 指令及汇编程序设计,2,Agenda,寻址模式指令格式AAPCS规范,寻址方式,立即寻址SUBS R0,R0,#1;R0-1-R0MOV R0,#0 xFF00;0 xFF00-R0寄存器偏移寻址MOV R0,R2,LSL#3;R2的值左移3位,结果放入R0,即R0=R2*8,寄存器间接寻址LDR R1,R2;将R2中的数值作为地址,取出此地址中的数据保存在R1中基址寻址Immediate Offset、Register Offset Scaled Register OffsetLDR R2,R3,#0 x0F;将R3中的数值加0 x0F作为地址,取出此地址的数值保存在R2中,多寄存器寻址LDMIA R1!,R2-R7,R12;将R1单元中的数据读出到R2-R7,R12,R1自动加1堆栈寻址STMFD SP!,R1-R7,LR;将R1-R7,LR入栈。满递减堆栈,块拷贝寻址STMIB R0!,R1-R7;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,增加方向为向上增长相对寻址BL ROUTE1;调用到ROUTE1子程序BEQ LOOP;条件跳转到LOOP标号处.LOOP MOV R2,#2.ROUTE1.,指令格式,基本格式数据处理类 S,内存访问类:BT,内的项是必须的内的项是可选的opcode指令助记符,如LDR,STR等cond执行条件,如EQ,NE等S是否影响CPSR寄存器的值Rd目标寄存器Rn第一个操作数的寄存器operand2 第二个操作数,第二个操作数#immed_8r常数表达式,必须是一个8位常数的偶数次循环移位合法常量:0 x3FC、0、0 xF0000000、200、0 xF0000001非法常量:0 x1FE、511、0 xFFFF、0 x1010、0 xF0000010AND R1,R2,#0 x0F;R2与0 x0F,结果保存在R1LDR R0,R1,#-4;读取R1地址上的存储器单元内容,且R1=R1-4,Rm 寄存器方式,操作数位寄存器的数值SUB R1,R1,R2;R1-R2-R1MOV PC,R0;PC=R0,程序跳转到制定地址LDR R0,R1,-R2;读取R1地址上的存储器单元内容并存入R0,且R1=R1-R2Rm,shift寄存器移位方式,将寄存器的移位结果作为操作数,但Rm值保持不变,形式1:type#n其中type 为 ASR(算术右移)、LSL(逻辑左移)、ROR(循环右移)、RRX(带扩展的循环右移1位)中的一种ADD R1,R1,R1,LSL#3;R1=R1*8形式2:type Rs 其中type ASR(算术右移)、LSL(逻辑左移)、ROR(循环右移)中的一种;Rs是偏移量寄存器,低8位有效,若其值大于或等于32则第二个操作数的结果为0(ASR,ROR例外),ARM汇编程序设计,文件格式汇编文件*.s引入文件*.INCC程序*.C头文件*.H汇编语句格式标号;注释标号顶格写,指令不可顶格书写标号后没有:程序中可以有空行分行用(用于比较长的语句),常量数字常量十进制 12,5,876,0十六进制 0 xFF,0 x1N进制 n-XXX,2-010111字符常量布尔常量,段定义AREA Hello,CODE,READONLYENTRYSTART MOV R7,#10MOV R6,#5ADD R6,R6,R7BEND,ARM汇编伪指令,在 ARM 汇编语言程序里,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,也就是不会生成机器码,仅仅是在编译器软件中起着格式化的作用,通常称这些特殊指令助记符为伪指令。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。在 ARM 的汇编程序中,有如下几种伪指令:数据常量定义伪指令、数据变量定义伪指令、内存分配伪指令及其他伪指令。,数据常量定义伪指令,数据常量定义伪指令EQU用于为程序中的常量、标号等定义一个等效的字符名称,类似于 C 语言中的#define。EQU语法格式:名称 EQU 表达式,类型;其中 EQU 可用“*”代替。名称为 EQU 伪指令定义的字符名称,当表达式为 32 位的常量时,可以指定表达式的数据类型,可以有以下三种类型:CODE16、CODE32 和 DATA。,数据变量定义伪指令(Cont.),数据变量定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。常见的数据变量定义伪指令有如下几种:(1)GBLA、GBLL 和GBLS 语法格式:GBLA(GBLL 或 GBLS)全局变量名 GBLA、GBLL 和 GBLS 伪指令用于定义全局变量,并将其初始化。其中:GBLA用于定义一个全局的数字变量,并初始化为 0;GBLL用于定义一个全局的逻辑变量,并初始化F(假);GBLS用于定义一个全局的字符串变量,并初始化为空;,数据变量定义伪指令(Cont.),(2)LCLA、LCLL 和LCLS 语法格式:LCLA(LCLL 或 LCLS)局部变量名 LCLA、LCLL 和 LCLS 伪指令用于定义一个 ARM 程序中的局部变量,并将其初始化。其中:LCLA伪指令用于定义一个局部的数字变量,并初始化为 0;LCLL伪指令用于定义一个局部的逻辑变量,并初始化为 F(假);LCLS 伪指令用于定义一个局部的字符串变量,并初始化为空;,数据变量定义伪指令(Cont.),(3)SETA、SETL 和SETS 语法格式:变量名 SETA(SETL 或 SETS)表达式 伪指令 SETA、SETL、SETS 用于给一个已经定义的全局变量或局部变量赋值。SETA 伪指令用于给一个数学变量赋值;SETL 伪指令用于给一个逻辑变量赋值;SETS 伪指令用于给一个字符串变量赋值;,数据变量定义伪指令(Cont.),(4)RLIST 语法格式:名称 RLIST 寄存器列表 RLIST 伪指令可用于对一个通用寄存器列表定义名称,使用该伪指令定义的名称可在 ARM 指令 LDM/STM 中使用。在 LDM/STM 指令中,列表中的寄存器访问次序为根据寄存器的编号由低到高,而与列表中的寄存器排列次序无关。,3 内存分配伪指令,内存分配伪指令一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。常见的数据定义伪指令有如下几种:(1)DCB 语法格式:标号 DCB 表达式(2)DCW(或DCWU)语法格式:标号 DCW(或 DCWU)表达式,3 内存分配伪指令(Cont.),(3)DCD(或DCDU)语法格式:标号 DCD(或 DCDU)表达式(4)DCFD(或DCFDU)语法格式:标号 DCFD(或 DCFDU)表达式(5)DCFS(或DCFSU)语法格式:标号 DCFS(或 DCFSU)表达式,3 内存分配伪指令(Cont.),(6)DCQ(或DCQU)语法格式:标号 DCQ(或 DCQU)表达式(7)SPACE 语法格式:标号 SPACE 表达式(8)MAP 语法格式:MAP 表达式,基址寄存器(9)FILED 语法格式:标号 FIELD 表达式,4 汇编控制伪指令,汇编控制伪指令用于控制汇编程序的执行流程,常用的汇编控制伪指令包括以下几条:(1)IF、ELSE、ENDIF 语法格式:IF 逻辑表达式 指令序列 1 ELSE 指令序列 2 ENDIF,汇编控制伪指令(Cont.),(2)WHILE、WEND 语法格式:WHILE 逻辑表达式 指令序列 WEND(3)MEXIT 语法格式:MEXIT MEXIT 用于从宏定义中跳转出去。,4 汇编控制伪指令(Cont.),(4)MACRO、MEND 语法格式:MACRO$标号 宏名$参数 1,$参数 2,指令序列 MEND MACRO、MEND伪指令可以将一段代码定义为一个整体,然后就可以在程序中通过宏指令多次调用该段代码。,2008年10月23日,南京大学计算机系,27,子程序结果返回规则,子程序中结果返回的规则如下:结果为一个32位整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和Rl返回;结果为一个浮点数时,可以通过浮点运算部件的寄存器f0、d0或s0来返回;结果为复合型浮点数(如复数)时,可以通过寄存器f0fn或d0dn来返回;对于位数更多的结果,需要通过内存来传递。,2008年10月23日,南京大学计算机系,28,ARM编译器保有的特定关键字,ARM编译器支持一些对ANSI C进行扩展的关键词。这些关键词用于声明变量、声明函数、对特定的数据类型进行一定的限制。,2008年10月23日,南京大学计算机系,29,用于声明函数的关键词(双下划线起头),_asm,内嵌汇编_inline,内联展开_irq,声明IRQ或FIQ的ISR_pure,函数不修改该函数之外的数据_softfp,使用软件的浮点连接件_swi,软中断函数_swi_indirect,软中断函数,2008年10月23日,南京大学计算机系,30,用于声明变量的关键词,register声明一个变量,告诉编译器尽量保存到寄存器中。_int64该关键词是long long的同义词。_global_reg将一个已经声明的变量分配到一个全局的整数寄存器中。,