寻址方式是指处理器根据指令中给出的地址信息来寻找物理地址的方式,目前ARM指令系统支持以下几种寻址方式:
也称为立即数寻址,这种寻址方式指令中就已经给出了操作数。也就是在执行指令的过程中,处理器取得指令的同时也取得了操作数,因此称为立即数寻址。例如:
ADD R0, #1 ;R0+1->R0
ADD R0, R0, #0x3F ;R0+0x3F->R0
在上面两条指令中,源操作数就是立即数,要求以“#”开始,对于十六进制的立即数,要求在“#”后面加“0x”或“&”。
即将寄存器中的数值作为操作数,是各类微处理器常用的寻址方式,也是效率较高的寻址方式。例如:
ADD R0, R1, R2 ;R1+R2->R0
该指令的执行效果是将R1和R2的值相加,将结果存入R0
寄存器间接寻址是以寄存器中的值作为操作数的地址,操作数本身存放在寄存器中。例如:
ADD R0, R1, [R2] ;R1+[R2]->R0
LDR R0, [R1] ;[R1]->R0
第一条指令,以寄存器R2的值作为操作数的地址,在寄存器中取得一个操作数后与R1相加,将结果存入寄存器R0。第二条指令,将寄存器中以R1为地址的值赋给R0。
基址变址寻址是把基址寄存器的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址。该方式常用于访问基地址附近的某些存储单元,一般有以下几种方式:
LDR R0, [R1, #4] ;[R1+4]->R0
第一条指令,将寄存器R1的值加上4作为操作数的有效地址,取得操作数后存入R0中。
LDR R0, [R1, #4]! ;[R1+4]->R0、R1+4->R1
第二条指令,将寄存器R1的值加上4作为操作数的有效地址,取得操作数后存入R0中,然后寄存器R1的值加上4个字节。
LDR R0, [R1], #4 ;[R1]->R0、R1+4->R1
第三条指令,将寄存器R1的值作为操作数的有效地址,取得操作数后存入R0中,然后寄存器R1的值加上4个字节。
LDR R0, [R1, R2] ;[R1+R2]->R0
第四条指令,将寄存器R1和R2的值相加作为操作数的有效地址,取得操作数后存入R0中。
使用多寄存器寻址,一条指令可以完成多个寄存器值的传送,一条指令最多可以传送16个通用寄存器的值。例如:
LDMIA R0, {R1,R2,R3,R4,} ;[R0]->R1,[R0+4]->R2,[R0+8]->R3,[R0+12]->R4
该指令后缀IA表示每次执行完读取/存储操作后,R0按字长增加,因此,指令可以将连续存储单元的值传送到R1~R4。
与基址变址寻址类似,相对寻址以程序计数器PC的当前值作为基地址,指令中的地址标号作为偏移量,将两者相加后得到操作数的有效地址。以下程序完成子程序的调用和返回,跳转指令BL采用了相对寻址方式:
BL NEXT ;跳转到子程序NEXT处执行指令
......
NEXT
......
MV PC, LR ;从子程序返回
堆栈是一种数据结构,按先进后出的方式工作,使用一个称为堆栈指针的专用寄存器指示当前的操作,堆栈指针总是指向堆栈顶端。当堆栈指针指向最后压入的数据时,称为满堆栈;当堆栈指针指向下一个将要压入的位置时,称为空堆栈。
根据堆栈的生成方式,可分为递增堆栈和递减堆栈。当堆栈由低地址向高地址生成时,称为递增堆栈,反之称为递减堆栈。排列组合后可得到4中类型的堆栈工作方式,ARM微处理器支持全部4种类型的堆栈工作方式。具体如下:
满递增堆栈:堆栈指针指向最后压入的数据,由低地址向高地址生成。
满递减堆栈:堆栈指针指向最后压入的数据,由高地址向低地址生成。
空递增堆栈:堆栈指针指向下一个将要压入数据的空位置,由低地址向高地址生成。
空递减堆栈:堆栈指针指向下一个将要压入数据的空位置,由高地址向低地址生成。