ARM处理器指令系统二 指令格式 存储器访问指令

来源:互联网 发布:软件开发费 税点 编辑:程序博客网 时间:2024/06/15 08:38
;文件名:TEST1.S;功能:实现两个寄存器相加;说明:使用ARMulate软件仿真调试AREA      RESET,CODE,READONLY      ;声明代码段RESETENTRY ;标识程序入口CODE32 ;声明32位ARM指令START   MOV R0,#0 ;设置参数MOV R1,#10LOOP     BL ADD_SUB ;调用子程序ADD_SUBB LOOP ;跳转到LOOPADD_SUBADDS R0,R0,R1 ;R0 = R0 + R1MOV PC,LR ;子程序返回END ;文件结束

先看上面这个两个寄存器相加的例子,分号后面的是注释,标号要顶格写,最后要有END声明结束


一指令格式

<opcode>  {cond}  {S}  <Rd>  ,<Rn> , {operand2}

其中<>号内的项是必须的,{}号内的项是可选的。

opcode:指令助记符; 

cond:执行条件;
S:是否影响CPSR寄存器的值;
Rd:目标寄存器; Rn:第1个操作数的寄存器;
operand2:第2个操作数;


1 、灵活的使用第2个操作数“operand2”能够提高代码效率。它有如下的形式:

(1)#immed_8r——常数表达式;

该常数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到。8位图立即数必须满足:能用8位长度的小窗把32位数据中所有的“1”圈起来,并且这个32位的数能通过某个8位的常数通过循环右移偶数位得到
 (2)Rm——寄存器方式;

在寄存器方式下,操作数即为寄存器的数值。比如:SUB R1,R1,R2
 (3)Rm,shift——寄存器移位方式;

将寄存器的移位结果作为操作数,但Rm值保持不变,移位方法如下 比如:ADD R1,R1,R1,LSL #3   ;R1=R1+R1*8=9R1

补充移位方式如下:

ASR #n 算术右移n位;  LSL #n 逻辑左移n位;  LSR #n 逻辑右移n位; ROR #n 循环右移n位;  RRX 带扩展的循环右移1位


2使用条件码“cond”可以实现高效的逻辑操作,提高代码效率。

举例比如EQ 代表相等 NE代表不相等 AL无条件执行 VS溢出 PL正数或零 MI负数 CC/LO无符号数小于 CS/HS无符号数大于或等于 HI 无符号数大于 LS无符号数小于或等于

示例代码如下:

C代码:

if( a > b) a++; else  b++;

对应的汇编代码:

CMP R0 R1 R0与R1比较

ADDHI R0,R0,#1 ;若R0>R1,则R0=R0+1

ADDLS R1,R1,#1 ;若R0≤1,则R1=R1+1


二 存储器访问指令

LDR指令用于从内存中读取单一字或字节数据存入寄存器中,
STR指令用于将寄存器中的单一字或字节数据保存到内存

存储器访问指令分为单寄存器操作指令和多寄存器操作指令。

单寄存器加载

助记符 说明 操作 条件码位置
LDR Rd,addressing 加载字数据Rd←[addressing],addressing索引 LDR{cond}

LDRB Rd,addressing 加载无符号字节数据    Rd←[addressing],addressing索引 LDR{cond}B

T以用户模式加载 BT以用户模式加载无符号字节数据  H加载无符号半字节数据  SB加载有符号字节数据  SH加载有符号半字节数据

单寄存器存储

LDR Rd,addressing  存储字数据

B存储字节数据 T以用户模式存储字数据BT以用户模式存储字节数据 H存储半字数据

LDR/STR指令寻址非常灵活,它由两部分组成,其中一部分为一个基址寄存器,可以为任一个通用寄存器;另一部分为一个地址偏移量。
地址偏移量有以下3种格式:
(1)立即数。立即数可以是一个无符号的数值。这个数据可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,#0x12]
(2)寄存器。寄存器中的数值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,R2]
(3)寄存器及移位常数。寄存器移位后的值可以加到基址寄存器,也可以从基址寄存器中减去这个数值。
如:LDR R1,[R0,R2,LSL #2]

从寻址方式的地址计算方法分,加载/存储指令有以下4种格式:

零偏移。如:LDR Rd,[Rn]
 前索引偏移。如:LDR Rd,[Rn,#0x04]!
 程序相对偏移。如:LDR Rd,labe1
 后索引偏移。如:LDR Rd,[Rn],#0x04(Rn为地址的空间的内容被修改)

最后举几个例子:

(1)、存储/加载字和无符号字节指令

LDR R2,[R5] ;将R5指向地址的字数据存入R2
STR R1,[R0,#0x04] ;将R1的数据存储到R0+0x04地址
LDRB R3,[R2],#1;将R2指向地址的字节数据存入R3,R2=R2+1
STRB R6,[R7] ;将R6 存入R7指向地址的字节数据
(2).加载/存储半字和有符号字节指令


LDRSB R1,[R0,R3]            ;将R0+R3地址上的字节数据存入R1,
                         ;高24位用符号扩展
LDRH R6,[R2],#2            将R2指向地址的半字数据存入R6,高16位用0扩展
                                                          ;读出后,R2=R2+2
STRH R1,[R0,#2]!               ;将R1的半字数据保存到R0+2地址,
                                                             ;只修改低2字节数据,R0=R0+2


多寄存器存取

多寄存器加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等

多寄存器加载/存储指令格式如下:
LDM {cond} <模式> Rn{!}, reglist{^}

STM {cond} <模式> Rn{!}, reglist{^}

堆栈操作和数据块传送指令类似,也有4种模式,它们之间的关系如下表所示


数据块传送存储 堆栈操作压栈  说明 数据块传送加载堆栈操作出栈 说明

STMDA STMED 空递减LDMDA LDMFA满递增

STMIA STMEA空递增 LDMIALDMFD 满递减

STMDB STMFD 满递减 LDMDB LDMEA 空递增

STMIB  STMFA满递增 LDMIB LDMED 空递减


;使用数据块传送指令进行堆栈操作 ;使用堆栈指令进行堆栈操作

STMDA R0!,{R5-R6} STMED SP!,{R5-R6}


LDMIB R0!,{R5-R6} LDMED SP!,{R5-R6}


寄存器和存储器交换指令

SWP指令用于将一个内存单元(该单元地址放在寄存器Rn中)的内容读取到一个寄存器Rd中,同时将另一个寄存器Rm的内容写入到该内存单元中。

指令格式如下:SWP{cond}{B}  Rd,Rm,[Rn]

其中,B为可选后缀,若有B,则交换字节,否则交换32位字;Rd用于保存从存储器中读入的数据;Rm的数据用于存储到存储器中,若Rm与Rn相同,则为寄存器与存储器内容进行交换;Rn为要进行数据交换的存储器地址。

SWP Rd,Rm,[Rn ] 寄存器和存储器字数据交换

SWPB Rd,Rm,[Rn ] 寄存器和存储器字节数据交换

































原创粉丝点击