ARM 处理器寻址方式
所谓寻址方式,是根据指令中的地址码来实现寻找真实操作数地址的方式,ARM处理器有9种基本寻址方式。
寄存器寻址
操作数的值在寄存器中,指令中的地址码指出的是寄存器编号,指令执行时直接取出寄存器值操作。
立即寻址
立即寻址指令中的操作码字段后面的地址码部分就是操作数本身,也就是说,数据就包含在指令当中,取出指令也就取出了可以立即使用的操作数(立即数)。
SUBS R0,R0,#1
MOV R0,#0xFF00
立即数要以“#”为前缀。
寄存器偏移寻址
寄存器偏移寻址是ARM指令集特有的寻址方式,当第2操作数是寄存器偏移方式时,第2个寄存器操作数在与第1个操作数结合之前,进行移位操作。
MOV R0,R2,LSL #3 ;R2的值左移3位,结果放入R0
ANDS R1,R1,R2,LSL R3 ;R2的值左移R3位,然后与R1相与,结果放入R1
可采用的移位操作如下:
- LSL: 逻辑左移(Logical Shift Left),寄存器中字的底端空出的位补0
- LSR: 逻辑右移(Logical Shift Right),寄存器的高端空出位补0
- ASR: 算术右移(Arithmetic Shift Right),移位过程中保持符号位不变,即如果源操作数为正数,则字的高端空出的位补0,否则补1
- ROR: 循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位
- RRX:带拓展标志的循环右移(Rotate Right Extended By 1place),操作数右移一位,高端空出的位用原C标志值填充
寄存器间接寻址
寄存器间接寻址指令中的地址码给出的是一个通用的寄存器编号,所需要的操作数保存在寄存器指定地址的存储单元中,即寄存器为操作数的地址指针
LDR R1,[R2] ;将R2中的数值作为地址,取出此地址中的数据保存在R1中
SWP R1,R1,[R2] ;将R2中的数值作为地址,取出此地址中的数值与R1中的值交换
基址寻址
基址寻址是将基址寄存器的内容与指令中给出的偏移量相加,形成操作数的有效地址,基址寻址用于访问基址附近的存储单元,常用于查表,数组操作,功能部件寄存器访问等。
LDR R2,[R3,#0x0F]
STR R1,[R0,#-2]
多寄存器寻址
多寄存器寻址就是一次可以传送几个寄存器的值,允许一条指令传送16个寄存器的任何子集或者所有寄存器。
LDMIA R1!,{R2-R7,R12} ;将R1单元中的数据读出到R2-R7,R12,R1自动加1
STMIA R0!,{R3-R6,R10} ;将R3-R6,R10中的数据保存到R0指向的地址,R0自动加1
使用多寄存器寻址指令时,寄存器子集的顺序由小到大的顺序排列,连续的寄存器可用“-”连接,否则,用“,”分割书写。
堆栈寻址
堆栈是按照特定顺序进行存取的存储区,操作顺序分为“后进先出”和“先进后出”,堆栈寻址时隐含的,它使用一个专门的寄存器(堆栈指针)指向一块存储区域(堆栈),指针所指向的存储单元就是堆栈的栈顶。存储器堆栈可分为两种:
- ** 向上生长: **向高地址方向生长,称为递增堆栈
- ** 向下生长: **向低地址方向生长,称为递减堆栈
堆栈指针指向最后压入的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,称为空堆栈。这样就有四种类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合。
- 满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向含有有效数据项的最高地址。指令如LDMFA、STMFA等。
- 空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA,STMEA等。
- 满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有有效数据的最低地址。指令如LDMFD,STMFD等。
- 空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如LDMED,STMED等。
STMFD SP!,{R1-R7,LR} ;将R1-R7,LR入栈。满递减堆栈
LDMFD SP!,{R1-R7,LR} ;数据出栈,满递减堆栈
块拷贝寻址
多寄存器传送指令用于一块数据从存储器的某一位置拷贝到另一位置。
STMIA R0!,{R1-R7} ;将R1-R7的数据保存到存储器中,存储器指针在保存第一个值后增加,增长方向为向上增长。
相对寻址
相对寻址是基址寻址的一种变通,由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论