寻址方式就是CPU根据指令中的地址信息,找出物理地址也就是内存地址的方式,通俗理解就是ARM指出内存地址的方式。

寻址的目的就是找出操作数,比如ARM要做一个除法运算,就需要除数和被除数,除数和被除数都是除法指令的操作数,要找到这些操作数,可以有多种方法,寻找操作数的过程就叫做寻址。(我个人理解)

ARM支持九种寻址方式:

  • 立即数寻址
  • 寄存器寻址
  • 寄存器偏移寻址
  • 寄存器间接寻址
  • 寄存器基址变址寻址
  • 多寄存器寻址
  • 相对寻址
  • 堆栈寻址
  • 块拷贝寻址

1.立即数寻址

立即数寻址就是直接将内存中的数据发给CPU作为操作数。注意,由于ARM是32位指令集,所以立即数的范围不可以超出0255,也就是说立即数的范围只能是0255。

格式:就是在立即数前面加上 # 来作为操作数

典型的例子就是直接对寄存器进行写值:

ldr r0, #254   ;将254写入r0寄存器
add r1, r2, #3 ;将r2寄存器中的值与3相加后,在写入r1寄存器

2.寄存器寻址

寄存器寻址就是直接将寄存器中的数值作为操作数:

ldr r1, r0      ;将r0寄存器中的值写到r0
add r3, r2, r1 ;将r1、r2寄存器的值相加,结果写入r3寄存器

3.寄存器间接寻址

还是利用了寄存器,只不过操作数不是寄存器中的值了,操作数在内存中,那怎么办?没事,操作数的地址就在寄存器中。所以寄存器间接寻址相当于以寄存器中的值作为内存地址,去内存中寻找操作数。

格式:在提供操作数地址的寄存器上加上[],比如[r0]

mov r0, #0X54000032
ldr r1, [r0] ;将地址为0X54000032的数据写入r1寄存器中

4.寄存器偏移寻址

以寄存器寻址为本,将寄存器中的数移位后作为操作数。

一共有6中移位操作:

LSL:逻辑左移(Logical Shift Left),寄存器中字的低端空出的位补0。

LSR:逻辑右移(Logical Shift Right),寄存器中字的高端空出的位补0。

ASL:算术左移(Arithmetic Shift Left),和逻辑左移LSL相同。

ASR:算术右移(Arithmetic Shift Right),移位过程中符号位不变,即如果源操作数是正数,则字的高端空出的位补0,否则补1。

ROR:循环右移(Rotate Right),由字的低端移出的位填入字的高端空出的位。

RRX:带扩展的循环右移(Rotate Right eXtended),操作数右移一位,高端空出的位用进位标志C的值来填充,低端移出的位填入进位标志位。

格式:rx, 移位命令 移位操作数

ldr r0, r1, lsl #3   ;将r1的值逻辑左移3位后写入r0
ldr r0, r1, ror r2 ;将r1的值循环右移r2中的值对应位后,写入r0

5.寄存器基址变址寻址

基址变址寻址是基于寄存器间接寻址的,只不过地址不再是寄存器中的值了,而是偏移后的值,这里的偏移值可以理解为地址相加值。

加上感叹号应该有优先执行的意思吧(个人理解)

格式:[rx, n],表示在rx寄存器所指向的地址上,再偏移(相加)n字节

ldr r0, [r1, #3]     ;地址为:r1值+3字节,指令执行完r1不变
ldr r0, [r1, #3]! ;地址为:r1值+3字节,指令执行完r1+3
ldr r0, [r1, #-1] ;地址为:r1值-1字节,指令执行完r1不变
ldr r0, [r1, r2] ;地址为:r1值+r2值
ldr r0, [r1], #4 ;地址为:r1值,但指令执行完后,r1值+4字节

6.批量寄存器寻址

批量寄存器寻址就是使用一个大括号{}包含多个寄存器

ldmia r0, {r1, r2, r3, r4}     ;将r1,r2,r3,r4中的数据依次放入R0指向的内存地址,r0+4指向的内存地址...
ldmia r0, {r1-r4} ;同上。

7.相对寻址

通过标号进行寻址,经常与跳转指令相配合使用

	bl heihei 

heihei:        ;跳转到heihei执行

8.堆栈寻址

堆栈即Stack,因为CPU的寄存器总是及其有限的,很多时候我们不得不使用内存来存储数据,比如进行多级跳转的时候,这时候堆栈就是一个很好的工具,每次跳转就将当前函数的返回地址存储到内存,最底层被调用的子函数会最先返回,就先将压入栈的现场返回,以此类推…,ARM使用SP(R13)作为栈指针,ARM设计的内存栈模型有2×2=4种

按照栈在内存增长的方向分为递增栈递减栈

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

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

根据堆栈指针SP指向的位置,又可以把堆栈分为满堆栈空堆栈两种。

满堆栈(Full Stack):SP始终指向栈顶元素,压栈的时候先移动SP,再将数据放入SP指向的地址。

空堆栈(Empty Stack):SP始终指向下一个将要放入元素的位置,压栈时先将数据放入SP指向的地址,再移动SP

最后,可以得到4种基本的堆栈类型:

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

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

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

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

stmfd sp!, {r1-r7, lr}  ;将r1到r7和lr的数据压入fd栈

9.块拷贝寻址

块拷贝寻址提供了一块内存和一组寄存器之间的拷贝,按照内存使用方式的不同,可以分为2×2=4种。地址增方向/地址减方向×先偏移/后偏移。堆栈寻址就可以看作是块拷贝寻址的的一个实例。

即:

IB:Increment Before Operating

IA:Increment After Operating

DB:Decrement Before Operating

DA:Decrement After Operating

STMIA  R0!,{R1—R7}  ;将R1-R7的寄存器中的值放入R0指向的地址,R0自动更新,指向操作后的地址

参考

ARM的九种寻址方式的更多相关文章

  1. ARM的9种寻址方式

    立即寻址 操作数是立即数,以“#”为前缀,表示 16 进制数值时以“0x”表示. 例: MOV   R0,#0xFF00   ;0xFF00 ->  R0 SUBS   R0,R0,#1     ...

  2. ARM指令分类及其寻址方式

    ARM指令分类及其寻址方式 一:ARM指令的分类 ARM指令集可以分为以下6类: •跳转指令: •数据处理指令: •程序状态寄存器(PSR)传输指令: •load/store指令: •协处理器指令: ...

  3. 浅谈UML的概念和模型之UML九种图

    1.用例图(use case diagrams) [概念]描述用户需求,从用户的角度描述系统的功能 [描述方式]椭圆表示某个用例:人形符号表示角色 [目的]帮组开发团队以一种可视化的方式理解系统的功能 ...

  4. UML九种图作用简介

    UML(统一建模语言):是面向对象的可视化建模语言. UML中有3种构造块:事物.关系和图,事物是对模型中最具有代表性的成分的抽象,关系是把事物结合在一起,图聚集了相关的事物 UML中有九种图如下: ...

  5. [UML]转:浅谈UML的概念和模型之UML九种图

    转自:http://blog.csdn.net/jiuqiyuliang/article/details/8552956 目录: UML的视图 UML的九种图 UML中类间的关系 上文我们介绍了,UM ...

  6. UML 小结(6)- UML九种图的比较与学习

    UML中的九种图: 用例图.类图.对象图.状态图.时序图.协作图.活动图.部署图.构件图. 1)用例图(Use Case Diagram) 它是UML中最简单也是最复杂的一种图.说它简单是因为它采用了 ...

  7. AngularJS 的那些内置九种过滤器

    ng内置了九种过滤 1. currency (货币处理) 使用currency可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币: {{num | currency : ...

  8. 深入解析spring中用到的九种设计模式

    转载请注明出处,文章首发于:http://itxxz.com/a/javashili/tuozhan/2014/0601/7.html 设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也 ...

  9. UML九种图 之 包图和对象图

    前言     对象图和包图依然是对系统的静态的描写叙述.UML九种图加上包图,事实上是十幅图. 包图     1.构成           2.包中的元素      类.接口.用例.构件.其他包等.( ...

随机推荐

  1. FreeRTOS消息队列

    FreeRTOS 的一个重要的通信机制----消息队列,消息队列在实际项目中应用较多. 一.消息队列的作用及概念: 消息队列就是通过 RTOS 内核提供的服务,任务或中断服务子程序可以将一个消息(注意 ...

  2. Java基础00-循环语句7

    1. for循环语句 1.1 循环结构 1.2 for循环语句的格式 执行流程图: 1.3 案例 (1)输出数据 (2)求和 (3)求偶数和 (4)水仙花 public static void mai ...

  3. ES6 数组Arrary 常用方法

    ES6 数组Arrary 常用方法: <script type="text/javascript"> // 操作数据方法 // arr.push() 从后面添加元素,返 ...

  4. python程序开机自启动

    windows下设置 因为服务器是windows环境 担心黑窗口不小心被关闭  因此想要让python程序在后台运行 只需要一下几步 1. 在启动python启动文件加入以下代码 import win ...

  5. 'utf-8' codec can't decode byte的解决办法

    参考链接:https://www.cnblogs.com/zyh19980816/p/11830065.html 问题:''utf-8' codec can't decode byte 0xa3 in ...

  6. Vue--之调试

    vue.文件的调试 方法:在chrome浏览器中,F12,在Sources中ctrl+F 查找leftMenu.vue, 打断点,F8完成加载

  7. Python3中datetime时区转换介绍与踩坑

    最近的项目需要根据用户所属时区制定一些特定策略,学习.应用了若干python3的时区转换相关知识,这里整理一部分记录下来. 下面涉及的几个概念及知识点: GMT时间:Greenwich Mean Ti ...

  8. 看视频学Bootstrap—在微软虚拟学院学习Bootstrap

    Bootstrap 是目前最流行的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB项目. 如果您希望在几个小时内对Bootstrap有一个直观的了解,观看微软虚拟学院(M ...

  9. webrtc编译

    webrtc编译 最近研究 libmediasoupclient,而 libmediasoupclient 又依赖 libwebrtc,所以首先就想着先在windows上编译一个webrtc的库,先是 ...

  10. CFS靶机

    nmap扫描 nmap -sV -p1-65535 192.168.1.135 thinkphp5.0版本 找到poc进行测试 http://192.168.1.135/index.php?s=ind ...