ARM学习笔记(八)--寻址方式

ARM 174浏览

寻址方式

9种:

立即数寻址

寄存器寻址

寄存器移位寻址

寄存器间接寻址

基址变址寻址

相对寻址

多寄存器寻址

块拷贝寻址

堆栈寻址

立即数寻址

在立即数寻址中,操作数本身直接在指令中给出,取出指令也就获得了操作数,这个操作数也称为立即数。

#后接0x&表示十六进制数,0b表示二进制数,0d或缺省表示十进制数。

:

ADD R0R1,#5 R0=R15

MOV R0,#0x55 R0=0x55

其中:操作数50x55就是立即数,立即数在指令中要以“#”为前缀,后面跟实际数值。

寄存器寻址

在寄存器寻址方式下,寄存器的值即为操作数。ARM指令普遍采用此种寻址方式。

例:

ADD R0R1R2 R0=R1R2

MOV R0R1 R0=R1

寄存器移位寻址

寄存器移位寻址的操作数由寄存器的数值做相应移位而得到。

移位的方式在指令中以助记符的形式给出,而移位的位数可用立即数或寄存器寻址方式表示。

例:

ADD R0R1R2ROR 5

R0=R1R2循环右移5

MOV R0R1LSL R3

R0=R1逻辑左移R3

移位操作在ARM指令集中不作为单独的指令使用,ARM指令集共有5种位移操作。

ARM指令集的5种位移操作

LSL逻辑左移 RxLSL <op1>

LSR逻辑右移 RxLSR <op1>

ASR算术右移 RxASR <op1>

ROR循环右移 RxROR <op1>

RRX带扩展的循环右移:RxRRX

寄存器间接寻址

寄存器中的值为操作数的物理地址,而实际的操作数存放在存储器中。

例:

STR R0[R1] [R1]=R0

LDR R0[R1] R0=[R1]

基址变址寻址

将寄存器(称为基址寄存器)的值与指令中给出的偏移地址量相加,所得结果作为操作数的物理地址。

例:

LDR R0[R1,#5] ; R0=[R1+5]

LDR R0[R1,R2] ; R0=[R1+R2]

相对寻址

相对寻址同基址变址寻址相似,区别只是将程序计数器PC作为基址寄存器,指令中的标记作为地址偏移量。

例:

BEQ process1

……

process1

……

多寄存器寻址

在多寄存器寻址方式中,一条指令可实现一组寄存器值的传送。

连续的寄存器间用“-”连接,否则用“,”分隔。

:

LDMIA R0{R1-R5}

R1=[R0],R2=[R0+4],R3=[R0+8]

R4=[R0+12]R5=[R0+16]

指令中IA表示在执行完一次Load操作后,R0自增4。该指令将以R0为起始地址的5个字数据分别装入R1R2R3R4R5中。

多寄存器寻址

多寄存器寻址一次可传送几个寄存器值,允许一条指令传送16个寄存器的任何子集或所有寄存器。多寄存器寻址指令举示例下:

块拷贝寻址

块拷贝寻址可实现连续地址数据从存储器的某一位置拷贝到另一位置。

:

LDMIA R0{R1-R5}

STMIA R1{R1-R5}

第一条指令从以R0的值为起始地址的存储单元中取出5个字的数据,第二条指令将取出的数据存入以R1的值为起始地址的存储单元中。

实际上是多寄存器寻址的组合。

堆栈寻址

堆栈寻址用于数据栈与寄存器组之间批量数据传输。

当数据写入和读出内存的顺序不同时,使用堆栈寻址可以很好的解决这问题。

例:

STMFD R13!{R0,R1,R2,R3,R4}

LDMFD R13!{R0,R1,R2,R3,R4}

第一条指令,将R0R4中的数据压入堆栈,R13为堆栈指针;

第二条指令,将数据出栈,恢复R0R4原先的值。

存储器堆栈可分为两种:

向上生长:向高地址方向生长,称为递增堆栈

向下生长:向低地址方向生长,称为递减堆栈