1、常用ARM及汇编指令用ARM指令及汇编包括 2指令集介绍 4ARM数据处理指令包括 7ARM伪指令介绍 9ARM汇编程序设计及一些格式要求说明 13用ARM指令及汇编包括1、ARM处理器寻址方式2、指令集介绍3、伪指令4、ARM汇编程序设计5、C与汇编混合编程ARM处理器寻址方式1、寄存器寻址:操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作MOV R1, R2;R2-R1SUB R0, R1,R2 ;R1-R2 -R02、立即寻址:立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令就取出了可以立即使用的
2、操作数SUBS R0,R0,#1;R0-1 - R0MOVR0,#0xff00 ;0xff00 - R0注:立即数要以#为前缀,表示16进制数值时以0x表示3、寄存器偏移寻址:是ARM指令集特有的寻址方式,当第2操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前选择进行移位操作MOV R0,R2,LSL #3 ;R2的值左移3位,结果存入R0,即R0 = R2 * 8ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相与操作,结果放入R1寄存器偏移寻址可采用的移位操作如下(1)、LSL(Logical Shift Left)逻辑左移,寄存器中字的低端空
3、出补0(2)、LSR(Logical Shift Right)逻辑右移,寄存器中字的高端空出补0(3)、ASR(Arthmetic Shift Right)算术右移,移位中保持符号位不变,即如果源操作数为正数,字高端空出补0,否则补1(4)、ROR(Rotate Right)循环右移,由字的低端移出的位填入高端空出的位(5)、RRX(Rotate Right eXtended by 1 place),操作数右移一位,左侧空位由CPSR的C填充4、寄存器间接寻址:寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需要的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针L
4、DRR1,R2;将R2中的数值作为地址,取出此地址中的数据保存在R1中SWP R1,R1,R2 ;将R2中的数值作为地址,取出此地址中的数值与R1中的值交换5、基址寻址:将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。LDR R2,R3,#0x0F;将R3的数值加0x0F作为地址,取出此地址的数值保存在R2中STR R1,R0,#-2 ;将R0中的数值减2作为地址,把R1中的内容保存到此地址位置6、多寄存器寻址:一次可以传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器LDMIA
5、 R1!,R2-R7,R12 ;将R1所指向的地址的数据读出到R2-R7,R12,R1自动更新STMIA R0!,R3-R6,R10;将R3-R6,R10中的数值保存到R0指向的地址,R0自动更新7、堆栈寻址:堆栈是特定顺序进行存取的存储区,堆栈寻址时隐含的使用一个专门的寄存器(堆栈指针),指向一块存储区域(堆栈),存储器堆栈可分为两种:向上生长:向高地址方向生长,称为递增堆栈向下生长:向低地址方向生长,称为递减堆栈如此可结合出四中情况:1、满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址,指令如 LDMFA,STMFA2、空递增:堆栈通过增大存储器的地址向上增长
6、,堆栈指针指向堆栈上的第一个空位置,指令如 LDMEA,STMEA3、满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址,指令如 LDMFD,STMFD4、空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置,指令如 LDMED,STMEDSTMFD SP!,R1-R7,LR ;将R1-R7,LR入栈,满递减堆栈LDMFD SP!,R1-R7,LR ;数据出栈,放入R1-R7,LR寄存器,满递减堆栈8、块拷贝寻址:多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置STMIA R0!,R1-R7 ;将R1-R7的数据保存到存储器中,存储
7、器指针在保存第一个值之后增加,方向为向上增长STMIB R0!,R1-R7 ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向上增长SIMDA R0!,R1-R7 ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后增加,方向为向下增长STMDB R0!,R1-R7 ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向下增长不论是向上还是向下递增,存储时高编号的寄存器放在高地址的内存,出来时,高地址的内容给编号高的寄存器9、相对寻址:是基址寻址的一种变通,由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到
8、的地址即为操作数的有效地址BL ROUTE1 ;调用到 ROUTE1 子程序BEQ LOOP ;条件跳转到 LOOP 标号处=指令集介绍指令格式: S,其中内的项是必须的,内的项是可选的opcode 指令助记符,如 LDR,STR等cond 执行条件,如 EQ,NE等S 是否影响CPSR寄存器的值,书写时影响CPSR,否则不影响Rd 目标寄存器Rn 第一个操作数的寄存器operand2 第二个操作数指令格式举例如下:LDR R0,R1 ;读取R1地址上的存储器单元内容,执行条件AL(无条件执行)BEQ DATAEVEN ;跳转指令,执行条件EQ,即相等跳转到DATAEVENADDS R1,R1
9、,#1 ;加法指令,R1+1 = R1 影响CPSR寄存器,带有SSUBNES R1,R1,#0xD ;条件执行减法运算(NE),R1-0xD = R1,影响CPSR寄存器,带有S条件码表条件码助记符标志含义EQZ=1相等NEZ=0不相等CS/HSC=1无符号数大于或等于CC/LOC=0无符号数小于MIN=1负数PLN=0正数VSV=1溢出VCV=0没有溢出HIC=1,Z=0无符号数大于LSC=0,Z=1无符号数小于或等于GEN=V带符号数大于或等于LTN!=V带符号数小于GTZ=0,N=V带符号数大于LEZ=1,N!=V带符号数小于或等于AL任何无条件执行(指令默认条件)条件码应用举例:1、
10、比较两个值大小,C代码如下:if(ab) a+;else b+;写出相应的ARM指令代码如下:设R0为a,R1为bCMP R0, R1 ; R0与R1比较ADDHI R0,R0,#1 ; 若R0R1,则R0=R0+1ADDLS R1,R1,#1 ; 若R0 R0,影响CPSR中的值ADC R1,R1,R3 ;(R1、R0) = (R1、R0)+(R3、R2)SBC指令:带借位减法指令,用寄存器Rn减去操作数2,再减去CPSR中的C条件标志位的非(即若C标志清零,则结果减去1),结果保存在Rd中使用SBC实现64位减法SUBS R0,R0,R2SBC R1,R1,R3 ;使用SBC实现64位减法
11、,(R1,R0) - (R3,R2)AND指令:按位与操作ANDS R0,R0,#0x01 ;取出最低位数据ORR指令:按位或操作ORR R0,R0,#0x0F ;将R0的低4位置1EOR指令是进行异或操作,BIC指令是位清除指令(遇1清0)TST:位测试指令TST R0,#0x01 ; 判断R0的最低位是否是为0TEQ:相等测试指令TEQ R0,R1; 比较R0与R1是否相等,也可看作相减,相等则为0,Z=1MUL指令:乘法指令MUL R1,R2,R3 ;R1=R2*R3MULS R0,R3,R7 ; R0=R3*R7,同时设置CPSR中的N位和Z位MLA是乘加指令,将操作数1和操作数2相乘
12、再加上第3个操作数,结果的低32位存入到Rd中UMULL是64位无符号乘法指令UMULL R0,R1,R5,R8 ; (R1、R0) = R5 * R8BL指令:带链接的跳转指令,指令将下一条指令拷贝到R14(即LR)链接寄存器中,然后跳转到指定地址运行BL指令用于子程序调用,例如:BL DELAYBX指令:带状态切换的跳转指令,例如 BX R0 ;跳转到R0指定的地址,并根据R0的最低位来切换处理器的状态MCR:ARM寄存器到协处理器寄存器的数据传送指令MRC:协处理器寄存器到ARM寄存器的数据传送指令MRC/MCR指令格式如下:MRC/MCR cond coproc,opcode1,Rd,
13、CRn,CRm,opcode2coproc是指令操作的协处理器名,标准名为pn,n为0-15opcode1 协处理器的特定操作码Rd MRC操作时,作为目标寄存器的协处理器寄存器,MCR操作时,作为ARM处理器的寄存器CRn 存放第1个操作数的协处理器寄存器CRm 存放第2个操作数的协处理器寄存器opcode2 可选的协处理器特定操作码MRC/MCR指令举例如下:mcr/mrc p15,0,r0,c1,c0,0SWI指令:SWI指令用于产生中断,从而实现用户模式变换到管理模式,CPSR保存到管理模式的SPSR中,执行转移到SWI向量SWI 0x123456 ;软中断,中断立即数 0x12345
14、6在SWI异常中断处理程序中,取出SWI立即数的步骤为:首先确定引起软中断的SWI指令是ARM指令还是THUMB指令,这可通过对SPSR访问得到,然后要取得该SWI指令的地址,这可通过访问LR寄存器得到,接着读出指令,分解出立即数程序代码如下:T_bit EQU 0x20 ;0010 0000SWI_Hander STMFD SP!,R0-R3,R12,LR ;现场保护 MRSR0,SPSR ;读取SPSR STMFD SP!,R0;保存SPSR TST R0, #T_bit ;测试T标志位,0为ARM,1为THUMB LDRNEH R0,LR,#-2;若是THUMB指令,读出产生中断的指令码
15、(16位) BICNER0,R0,#0xFF00;取得THUMB指令的8位立即数 LDREQR0,LR,#-4 ;若是ARM指令,读取产生中断的指令码(32位) BICEQ R0,R0,#0xFF000000 ;取得ARM指令的24位立即数 BL C_SWI_Handler LDMFD SP!,R0-R3,R12,PC;SWI异常中断返回MRS指令:读状态寄存器指令,在ARM处理器中,只有MRS指令可以从状态寄存器CPSR或SPSR读出到通用寄存器MRS R1,CPSR ;将CPSR状态寄存器读取,保存到R1MRS R2,SPSR ;将SPSR状态寄存器读取,保存到R2MRS应用:1、使能IR
16、Q中断ENABLE_IRQMRS R0,CPSRBIC R0,R0,#0x80 ;1000 0000MSR CPSR,R0MOV PC,LR2、禁止IRQ中断DISABLE_IRQMRS R0,CPSRORR R0,R0,#0x80MSR CPSR,R0MOV PC,LRMSR:写状态寄存器指令,在ARM处理器中,只有MSR指令可以直接设置状态寄存器CPSR或SPSR=ARM伪指令介绍ARM伪指令不是ARM指令集中的指令,只是为了编程方便编译器定义了伪指令ARM地址读取伪指令有四条,分别是ADR 伪指令ADRL 伪指令LDR 伪指令NOP 伪指令作用的范围不一样,由小到大: ADR,ADRL,
17、LDRADR、ADRL指令将基于PC相对偏移的地址读取到存储器中,例如ADR R0 , DISP_TAB ; 加载转换表地址LDR R1, R0,R2 ;使用R2作为参数,进行查表.DISP_TABDCB 0xc0,0xf9,0xa4,0x99,0x92,0x82,0xf8,0x80LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器,前加 =LDR R0,=0x123456 ;加载32位立即数0x123456LDR R0,=DATA_BUF+60 ;加载DATA_BUF地址+60NOP是空操作伪指令宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏,当程序被汇编
18、时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令符号定义伪指令1、全局变量声明:GBLA、GBLL 和 GBLS2、局部变量声明:LCLA、LCLL 和 LCLS3、变量赋值:SETA、SETL、和 SETS4、为一个通用寄存器列表定义名称:RLIST5、为一个协处理器的寄存器定义名称:CN6、为一个协处理器定义名称:CP最后一个字符 A代表算术变量,初始值为0,L代表逻辑变量,初值为FALSE,S代表字符串,初值为空伪指令应用举例如下:MACRO ;声明一个宏SENDDAT $dat ;宏的原型 $表示后面是变量LCLA bitno;声明一个局部算术变量.bitno SETA
19、8 ;设置变量值为8.MEND ;结束RLIST指令格式:name RLIST reglist,例如: LoReg RLIST R0-R7 ;定义寄存器列表LoRegCN指令的用法:name CN expr,其中name是要定义的协处理器的寄存器名称,expr对应的协处理器的寄存器编号,数值范围 0 15MemSet CN 1;将协处理器的寄存器1名称定义为 MemSetCP指令的用法,举例如下:DivRun CP 5;将协处理器5名称定义为DivRun数据定义伪指令:1、声明一个文字池:LTORG2、定义一个结构化的内存表的首地址:MAP 或 3、定义结构化内存表中的一个数据域:FIELD
20、或 #4、分配一块内存空间,并用0初始化: SPACE 或 %5、分配一段字节内存单元,并用指定的数据初始化: DCB6、分配一段字的内存单元,并用指令的数据初始化: DCD 和 DCDU7、分配一段双字的内存单元,并用64位整数数据初始化: DCQ 和 DCQU8、分配一段半字的内存单元,并用指定的数据初始化: DCW 和 DCWULTORG 用于声明一个文子池,在使用LDR伪指令时,要在适当的地址加入LTORG声明文子池,这样就会把要加载的数据保存在文子池内,再用ARM的加载指令读出数据(若没有使用LTORG声明文子池,则汇编器会在程序末尾自动声明)LTORG伪指令应用举例如下:.LDR
21、R0,=0x12345678ADD R1,R1,R0MOV PC,LRLTORG ;声明文子池DCD0x333DCD 0x555MAP 用于定义一个结构化的内存表的首地址,与MAP同义MAP 0x00, R9;定义内存表的首地址为R9FIELD 用于定义一个结构化内存表的数据域,#与FIELD同义 _ISR_STARTADDRESS ; is synonym for MAPHandleReset # 4 ; 定义数据域 HandleReset,长度为4字节SPACE用于分配一块内存单元,并用0初始化,%与SPACE同义伪指令应用举例如下:AREA DataRAM,DATA,READWROTE
22、;声明一数据段,名为DataRAMDataBuf SPACE1000 ;分配1000字节空间DCB伪指令格式:label DCB expr,expr .加的代表可有可无,DCD、DCW指令格式与DCB基本相同ASSERT为断言错误伪指令,在汇编编译器对汇编程序的第二遍扫描中,若其中ASSERT条件不成立,ASSERT伪指令将报告该错误信息ASSERT TopTemp ;断言Top 不等于 TempASSERT :DEF:ENDIAN_CHANGE汇编控制伪指令1、条件汇编控制:IF、ELSE 和 ENDIFIF、ELSE 和 ENDIF 伪指令能够根据条件把一段代码包括在汇编程序内或将其排除在程序之外 与 IF同义 ,| 与 ELSE 同义, 与 ENDIF 同义
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1