用ARM指令及汇编包括 ................................................................................................................ 2 指令集介绍....................................................................................................................................... 4 ARM数据处理指令包括 ................................................................................................................. 7 ARM伪指令介绍 ................................................................................................................................ 9 ARM汇编程序设计及一些格式要求说明 ................................................................................... 13
用ARM指令及汇编包括
1、ARM处理器寻址方式 2、指令集介绍 3、伪指令
4、ARM汇编程序设计 5、C与汇编混合编程
ARM处理器寻址方式
1、寄存器寻址:操作数的值在寄存器中,指令中的地址码字段指出的是寄存器编号,指令执行时直接取出寄存器值操作 MOV R1, R2 ;R2->R1
SUB R0, R1,R2 ;R1-R2 -> R0 2、立即寻址:立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令就取出了可以立即使用的操作数 SUBS R0,R0,#1 ;R0-1 -> R0 MOV R0,#0xff00 ;0xff00 -> R0
注:立即数要以\为前缀,表示16进制数值时以\表示
3、寄存器偏移寻址:是ARM指令集特有的寻址方式,当第2操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前选择进行移位操作 MOV R0,R2,LSL #3 ;R2的值左移3位,结果存入R0,即R0 = R2 * 8 ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后和R1相与操作,结果放入R1
寄存器偏移寻址可采用的移位操作如下
(1)、LSL(Logical Shift Left)逻辑左移,寄存器中字的低端空出补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、寄存器间接寻址:寄存器间接寻址指令中的地址码给出的是一个通用寄存器的编号,所需要的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针
LDR R1,[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 R1!,{R2-R7,R12} ;将R1所指向的地址的数据读出到R2-R7,R12,R1自动更新
STMIA R0!,{R3-R6,R10} ;将R3-R6,R10中的数值保存到R0指向的地址,R0自动更新
7、堆栈寻址:堆栈是特定顺序进行存取的存储区,堆栈寻址时隐含的使用一个专门的寄存器(堆栈指针),指向一块存储区域(堆栈),存储器堆栈可分为两种:
向上生长:向高地址方向生长,称为递增堆栈 向下生长:向低地址方向生长,称为递减堆栈 如此可结合出四中情况:
1、满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址,指令如 LDMFA,STMFA
2、空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置,指令如 LDMEA,STMEA
3、满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址,指令如 LDMFD,STMFD
4、空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置,指令如 LDMED,STMED
STMFD SP!,{R1-R7,LR} ;将R1-R7,LR入栈,满递减堆栈
LDMFD SP!,{R1-R7,LR} ;数据出栈,放入R1-R7,LR寄存器,满递减堆栈
8、块拷贝寻址:多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置
STMIA R0!,{R1-R7} ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后增加,方向为向上增长
STMIB R0!,{R1-R7} ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向上增长
SIMDA R0!,{R1-R7} ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后增加,方向为向下增长
STMDB R0!,{R1-R7} ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前增加,方向为向下增长
不论是向上还是向下递增,存储时高编号的寄存器放在高地址的内存,出来时,
高地址的内容给编号高的寄存器
9、相对寻址:是基址寻址的一种变通,由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址 BL ROUTE1 ;调用到 ROUTE1 子程序 BEQ LOOP ;条件跳转到 LOOP 标号处
================================================================================================================
指令集介绍
指令格式:
S 是否影响CPSR寄存器的值,书写时影响CPSR,否则不影响 Rd 目标寄存器
Rn 第一个操作数的寄存器 operand2 第二个操作数
指令格式举例如下:
LDR R0,[R1] ;读取R1地址上的存储器单元内容,执行条件AL(无条件执行)
BEQ DATAEVEN ;跳转指令,执行条件EQ,即相等跳转到DATAEVEN ADDS R1,R1,#1 ;加法指令,R1+1 => R1 影响CPSR寄存器,带有S
SUBNES R1,R1,#0xD ;条件执行减法运算(NE),R1-0xD => R1,影响CPSR寄存器,带有S
条件码表 条件码助记符 EQ NE CS/HS CC/LO MI PL VS VC 标志 Z=1 Z=0 C=1 C=0 N=1 N=0 V=1 V=0 含义 相等 不相等 无符号数大于或等于 无符号数小于 负数 正数 溢出 没有溢出 HI LS GE LT GT LE AL C=1,Z=0 C=0,Z=1 N=V N!=V Z=0,N=V Z=1,N!=V 无符号数大于 无符号数小于或等于 带符号数大于或等于 带符号数小于 带符号数大于 带符号数小于或等于 任何无条件执行(指令默认条件) 条件码应用举例:
1、比较两个值大小,C代码如下: if(a>b) a++; else b++;
写出相应的ARM指令
代码如下:设R0为a,R1为b
CMP R0, R1 ; R0与R1比较 ADDHI R0,R0,#1 ; 若R0>R1,则R0=R0+1 ADDLS R1,R1,#1 ; 若R0<=R1,则R1=R1+1
2、若两个条件均成立,则将这两个数值相加 C代码为: if((a!=10)&&(b!=20)) a=a+b; 对应的ARM指令为:
CMP R0,#10 ;比较R0是否为10
CMPNE R1,#20 ;若R0不为10,则比较R1是否为20
ADDNE R0,R0,R1; 若R0不为10且R1不为20,则执行 R0 = R0+R1
3、若两个条件有一个成立,则将这两个数值相加 C代码为: if((a!=10)||(b!=20)) a=a+b; 对应的ARM指令为: CMP R0,#10 CMPEQ R1,#20 ADDNE R0,R0,R1
ARM存储访问指令:
LDR、STR、LDM、STM、SWP
LDR/STR:加载/存储字和无符号字节指令
从寻址方式的地址计算方法分,加载/存储指令有以下4种形式: 1,零偏移:LDR Rd,[Rn]
2,前索引偏移: LDR Rd,[Rn,#0x04]!,LDR Rd,[Rn,#-0x04] Rn不允许为R15 3,程序相对偏移:LDR Rd,label,label为程序标号,该形式不能使用后缀! 4,后索引偏移: LDR Rd,[Rn],#0x04,Rn不允许是R15
指令举例如下:
LDR R2,[R5] ;加载R5指定地址上的数据(字),放入R2中