联大大纲—通信电子 ;教师介绍; 单片机课程学习经验- 学习路线图; 1.概述 -应用 -定义 -特点 -构成; 2.嵌入式处理器 —DIY CPU处理器ARM处理器Cortex-A8S5PV210讨论; 3.汇编语言 -作业 4.Bootloader -作业 5.Linux内核移植 6.嵌入式Linux程序设计 7.图形用户接口QT 8.其他框架介绍; 9.嵌入式物联网应用系统设计

寻址方式

定义(问题引出):操作数是一条指令的操作对象。在指令执行前,CPU需要按照在指令中给定的方式找到操作数。在指令中给出操作数存放地址的方式,简称寻址方式。处理器可依据给定的寻址方式来获得操作数存放的地址,进而找到操作数。

种类(9种):立即数寻址、寄存器寻址、寄存器移位寻址、寄存器间接寻址、基址变址寻址、相对寻址、多寄存器寻址、块拷贝寻址、堆栈寻址。

1 立即数寻址 :

也称立即寻址,立即数作为操作数在指令中给出。立即数在指令中要以“#”为前缀,后面跟实际数值。数值前缀0x表示十六进制数,0b表示二进制数。

 

MOV  R1,5      ;R1 =5 

MOV  R0,#0xFF000    ;R0 = 0xFF000

2 寄存器寻址 :

操作数存放在寄存器中,通过寄存器可以找到该数值。

 

MOV  R1,  R2  ;R1 =R2

ADD  R0R1#3   ;R0=R13

3 寄存器间接寻址 :

寄存器中的值为存储操作数单元的物理地址,寄存器起到指针作用。寄存器间接寻址指令举例如下:

 

MOV  R1,0xE0200000     ;R1 = 0xE0200000

MOV  R0,#3      ;R0 = 3

STR    R0, [R1]     ;[E0200000] = 3

4 寄存器移位寻址 :

寄存器移位寻址是在寄存器寻址得到操作数后再进行移位操作,最终得到操作数。移位的方式在指令中以助记符形式给出,而移位的位数可用立即数或寄存器寻址方式表示。

 

ADD  R0R1R2ROR 5    ;R0=R1+(R2>>5

 

ARM指令集提供的移位操作指令如下:

(1)LSL:  逻辑左移(Logical Shift Left),移出空位补0

(2)LSR: 逻辑右移(Logical Shift Right

(3)ASL: 算术左移(Arithmetic Shift Left)。

(4)ASR:算术右移(Arithmetic Shift Right)。

(5)ROR:循环右移(Rotate Right)。

(6)RRX进位标志位C作为D32,Rx组成33位数,执行循环右移操作。

5 基址变址寻址 :

Rx寄存器(基址寄存器)的值与指令中给出的偏移地址量相加,所得结果作为存放操作数存储单元的物理地址。选项“!”表示指令执行完毕把最后的数据地址写到Rx

 

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

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

ldmia  r0!, {r3 - r10}  ;copy from source address [r0]

6 相对寻址 :

相对寻址与基址变址寻址相似,区别只是将程序计数器PC作为基址寄存器,指令中的地址标号作为偏移量,将两者相加之后得到操作数的存放地址。

 

B          process1  ;无条件跳转到process1处执行指令

……   ;若干其它指令

process1   MOV  R0#3 

;定义指令标号为process1,可供B指令指定跳转位置

……   ;若干其它指令

7多寄存器寻址

在多寄存器寻址方式中,可以使用一条指令实现一组寄存器值的传送。连续的寄存器间需要使用“-”符号连接,否则用“,”分隔。多寄存器寻址指令举例如下:

LDMIA R0{R1-R4,R6}      ;R1=[R0], R2=[R0+4], R3=[R0+8], R4=[R0+12], R6=[R0+16]

多寄存器寻址方式中,基址寄存器传送一个数据后有4种增长方式,即:

IAIncrement After Operating):   每次传送后地址增加4

IBIncrement Before Operating):  每次传送前的地址增加4

DADecrement After Operating):   每次传送后地址减少4

DBDecrement Before Operating):  每次传送前地址减少4

在多寄存器寻址指令举例中,指令为寄存器赋值语句。源地址为寄存器R0所指向的内存地址,目的地址为寄存器,为每个指定寄存器赋值之后,R0的内容增4来得到存放下一个数据的内存地址。指令中在助记符字段附加了内存地址增长方式的条件,表示每次传送后地址增加4,依次从源地址开始的205*4)个连续存储单元取出数据(字长为4子节)赋值给5个寄存器(R1, R2, R3, R5,R6)。

8块拷贝寻址

块拷贝寻址可实现数据块的拷贝和复制。块拷贝寻址指令举例如下:

LDMIA  R0{R1-R5}        /*从以R0的值为起始地址的存储单元(源数据块首地址)读出5个字(字长为4字节)的数据,依次存入R1-R5寄存器(目的地址)。*/

STMIA  R1{R1-R5}        /*R1-R5中的数值(源数据块)依次存入以R1寄存器中的值为起始地址的存储单元(目的首地址),完成数据块存储。IA表示每次传送后地址增加4*/

9堆栈寻址

堆栈寻址用于数据栈与寄存器组之间批量数据传输,实现寄存器数据入栈的保护和出栈的恢复。 R13用于堆栈指针,等同于SPStack Pointer)。堆栈是一种数据结构,按先进后出(FILO First In Last Out)的方式工作,使用堆栈指针指示当前操作位置,SP总是指向栈顶。

1)根据堆栈的生成方式不同,可以把堆栈分为递增堆栈和递减堆栈两种类型。

递增堆栈:向堆栈写入数据时,堆栈由低地址向高地址生长。

递减堆栈:向堆栈写入数据时,堆栈由高地址向低地址生长。

2)根据SP指向的位置,又可以把堆栈分为满堆栈(Full Stack)和空堆栈(Empty Stack)两种类型。

满堆栈(Full Stack):SP指向最后压入堆栈的数据。满堆栈在向堆栈存放数据时的操作是先移动SP指针,然后存放数据。在从堆栈取数据时,先取出数据,随后移动SP指针。这样保证了SP一直指向有效的数据。

空堆栈(Empty Stack):堆栈指针SP指向下一个将要放入数据的空位置。空堆栈在向堆栈存放数据时的操作是先放数据,然后移动SP指针。在从堆栈取数据时,是先移动指针,再取数据。这种操作方式保证了堆栈指针一直指向一个空地址(没有有效数据的地址)。

3)上述两种堆栈类型的组合,可以得到四种基本的堆栈类型组合。

满递增堆栈(FA):堆栈指针指向最后压入的数据,且由低地址向高地址生长。

满递减堆栈(FD):堆栈指针指向最后压入的数据,且由高地址向低地址生长。

空递增堆栈(EA):堆栈指针指向下一个要压入数据的地址,由低地址向高地址生长。

空递减堆栈(ED):堆栈指针指向下一个要压入数据的地址,由高地址向低地址生长。

在编写程序中,堆栈操作建议采用统一标准。堆栈寻址指令举例如下:

STMFD  R13!{R0,R1,R2,R3,R4}      ;R0-R4中的数据压入堆栈,R13为堆栈指针

LDMFD  R13!{R0,R1,R2,R3,R4}      ;将数据弹出栈,依次送到R0-R4