寻址是指处理器根据指令中给出得地址信息,找出操作数所存放得物理地址,实现对操作数得访问。
下面根据指令中给出的操作数的不同形式依次详细介绍寻址方式:
1.立即寻址
1.立即寻址也叫立即数寻址,指令的操作码字段后面的地址码部分不是操作数地址而是操作数本身,包含在指令的32位编码中。
2.立即数前要加前缀“#”。
ADD R0,R0,#1 ; //把R0的值加1的和在放到R0中
MOV R0,#0x00ff ;//把0x00ff直接放在R0中
2.寄存器寻址
1.寄存器寻址是指将操作数放在寄存器中,指令中地址码部分给出寄存器编号。
2.这是各类微处理器常用的一种有较高执行效率的寻址方式。
ADD R0,R1,R2 ;//把R1和R2上的值的和放在R0上
MOV R0,R1 ;//把R1上的值放到R0上
3.寄存器间接寻址
操作数存放在存储器中,并将所存放的存储单元地址放入某一通用寄存器中,在指令中的地址码部分给出该通用寄存器的编号。
LDR R0,[R1];//将寄存器R1中存放的值0xA0000008作为存储器地址,将该存储单元中的数据0x00000003传送到寄存器R0中。
SWP R1,R1,[R2];//将R2中的数值作为地址,取出地址中的数值与R1中的值交换。
4.寄存器移位寻址
1.该指令中,寄存器的值在被送到ALU之前,先进行移位操作。
移位的方式由助记符给出,移位的位数可由立即数或寄存器直接寻址方式表示。
2.采用的移位操作有:
LSL:逻辑左移,寄存器值低端空出的位补0。
LSR:逻辑右移,寄存器值高端空出的位补0。
ASR:算术右移,算术移位操作对象是有符号,位移过程中要保证操作数的符号不变,若操作数是正数,高端空出位补0;若操作数是负数,高端空出位补1.
ROR:循环右移,从低端一处的位填入高端空出的位中。
RRX:带扩展的循环右移,操作数右移1位,高端空出的位用C标志位.填充。
MOV R0,R1,LSL,#2;//将R1中的数逻辑左移两位
ADD R0,R1,R2,LSR,#3;//将R1+R2的数逻辑右移3位放到R0
5.变址寻址
变址寻址方式是将某个寄存器(基址寄存器)的值与指令中给出的偏移量相加,形成操作数的有效地址,再根据该有效地址访问存储器。
该寻址方式常用于访问在基址附近的存储单元。
LDR R0,[R1,#2];//将R1寄存器的值0xA0000008加上位移量2,形成操作数的有效地址,将该有效地址单元中的数据传送到寄存器R0中。
6.多寄存器寻址
多寄存器寻址方式可以在一条指令中传送多个寄存器的值,一条指令最多可以传送16个通用寄存器的值。
连续的寄存器之间用“-”连接,不连续的中间用“,”分隔。
LDMIA R0!,{R1-R3,R5};//将R0寄存器的值0xA0000004作为操作数地址,将存储器中该地址开始的连续单元的数据传送到寄存器R1,R2,R3,R5中。
7.相对寻址
相对寻址方式就是以程序寄存器(PC)为基址寄存器,以指令中的地址标号为偏移量,两者相加形成操作数的有效地址。
偏移量指出的是当前指令和地址标号之间的相对位置。
子程序调用指令即是相对寻址方式。
BL ADDR1;//跳转到子程序ADDR1处执行
ADDR1:
...
MOV PC,LR;//从子程序返回
8.堆栈寻址
堆栈是按“先进后出”或“先出后进”方式进行存取的存储区。
堆栈寻址是隐含的,使用一个叫作堆栈指针的专门寄存器,指示当前堆栈的栈顶。
根据堆栈的生成方式不同,分为递增堆栈和递减堆栈。当堆栈向高地址方向生长时,叫作递增堆栈(向上生长);当堆栈向低地址方向生长时,叫作递减堆栈(向下生长)。
堆栈指针指向最后压入堆栈的数据时,称为满堆栈;堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈。
四种堆栈工作方式:满递增堆栈(FA),满递减堆栈(FD),空递增堆栈(EA),空递减堆栈(ED)。
STMFD SP!,{R1-R3,LR} ;//将寄存器R1-R3和LR压入堆栈,满递减堆栈
LDMFD SP!,{R!-R3,LR} ;//将堆栈数据出栈,放入寄存器R1-R3和LR
9.块复制寻址
块复制寻址方式时多寄存器传送指令LDM/STM的寻址方式。
LDM/STM指令可以将存储器中的一个数据块复制到多个寄存器中,或将多个寄存器中的值复制到存储器中。
根据基地址的增长方向是向上还是向下,以及地址的增减与指令操作的先后顺序(操作先进行还是地址先增减)的关系,有四种寻址方式:
IB:地址先增加再完成操作
IA:先完成操作再地址增加
DB:地址先减少再完成操作
DA:先完成操作再地址减少
STMIA R0!,{R1-R7};//将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后改变,反向为向上增长。
STMIB R0!,{R1-R7};//将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前改变,反向为向上增长。
STMDA R0!,{R1-R7};//将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之后改变,反向为向下增长。
STMDB R0!,{R1-R7};//将R1-R7的数据保存到存储器中,存储器指针在保存第一个值之前改变,反向为向上增长。