ARM的九种寻址方式
寻址方式就是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的九种寻址方式的更多相关文章
- ARM的9种寻址方式
立即寻址 操作数是立即数,以“#”为前缀,表示 16 进制数值时以“0x”表示. 例: MOV R0,#0xFF00 ;0xFF00 -> R0 SUBS R0,R0,#1 ...
- ARM指令分类及其寻址方式
ARM指令分类及其寻址方式 一:ARM指令的分类 ARM指令集可以分为以下6类: •跳转指令: •数据处理指令: •程序状态寄存器(PSR)传输指令: •load/store指令: •协处理器指令: ...
- 浅谈UML的概念和模型之UML九种图
1.用例图(use case diagrams) [概念]描述用户需求,从用户的角度描述系统的功能 [描述方式]椭圆表示某个用例:人形符号表示角色 [目的]帮组开发团队以一种可视化的方式理解系统的功能 ...
- UML九种图作用简介
UML(统一建模语言):是面向对象的可视化建模语言. UML中有3种构造块:事物.关系和图,事物是对模型中最具有代表性的成分的抽象,关系是把事物结合在一起,图聚集了相关的事物 UML中有九种图如下: ...
- [UML]转:浅谈UML的概念和模型之UML九种图
转自:http://blog.csdn.net/jiuqiyuliang/article/details/8552956 目录: UML的视图 UML的九种图 UML中类间的关系 上文我们介绍了,UM ...
- UML 小结(6)- UML九种图的比较与学习
UML中的九种图: 用例图.类图.对象图.状态图.时序图.协作图.活动图.部署图.构件图. 1)用例图(Use Case Diagram) 它是UML中最简单也是最复杂的一种图.说它简单是因为它采用了 ...
- AngularJS 的那些内置九种过滤器
ng内置了九种过滤 1. currency (货币处理) 使用currency可以将数字格式化为货币,默认是美元符号,你可以自己传入所需的符号,例如我传入人民币: {{num | currency : ...
- 深入解析spring中用到的九种设计模式
转载请注明出处,文章首发于:http://itxxz.com/a/javashili/tuozhan/2014/0601/7.html 设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也 ...
- UML九种图 之 包图和对象图
前言 对象图和包图依然是对系统的静态的描写叙述.UML九种图加上包图,事实上是十幅图. 包图 1.构成 2.包中的元素 类.接口.用例.构件.其他包等.( ...
随机推荐
- FreeRTOS消息队列
FreeRTOS 的一个重要的通信机制----消息队列,消息队列在实际项目中应用较多. 一.消息队列的作用及概念: 消息队列就是通过 RTOS 内核提供的服务,任务或中断服务子程序可以将一个消息(注意 ...
- Java基础00-循环语句7
1. for循环语句 1.1 循环结构 1.2 for循环语句的格式 执行流程图: 1.3 案例 (1)输出数据 (2)求和 (3)求偶数和 (4)水仙花 public static void mai ...
- ES6 数组Arrary 常用方法
ES6 数组Arrary 常用方法: <script type="text/javascript"> // 操作数据方法 // arr.push() 从后面添加元素,返 ...
- python程序开机自启动
windows下设置 因为服务器是windows环境 担心黑窗口不小心被关闭 因此想要让python程序在后台运行 只需要一下几步 1. 在启动python启动文件加入以下代码 import win ...
- 'utf-8' codec can't decode byte的解决办法
参考链接:https://www.cnblogs.com/zyh19980816/p/11830065.html 问题:''utf-8' codec can't decode byte 0xa3 in ...
- Vue--之调试
vue.文件的调试 方法:在chrome浏览器中,F12,在Sources中ctrl+F 查找leftMenu.vue, 打断点,F8完成加载
- Python3中datetime时区转换介绍与踩坑
最近的项目需要根据用户所属时区制定一些特定策略,学习.应用了若干python3的时区转换相关知识,这里整理一部分记录下来. 下面涉及的几个概念及知识点: GMT时间:Greenwich Mean Ti ...
- 看视频学Bootstrap—在微软虚拟学院学习Bootstrap
Bootstrap 是目前最流行的 HTML.CSS 和 JS 框架,用于开发响应式布局.移动设备优先的 WEB项目. 如果您希望在几个小时内对Bootstrap有一个直观的了解,观看微软虚拟学院(M ...
- webrtc编译
webrtc编译 最近研究 libmediasoupclient,而 libmediasoupclient 又依赖 libwebrtc,所以首先就想着先在windows上编译一个webrtc的库,先是 ...
- CFS靶机
nmap扫描 nmap -sV -p1-65535 192.168.1.135 thinkphp5.0版本 找到poc进行测试 http://192.168.1.135/index.php?s=ind ...