LDR 和 ADR 彻底详解
0.什么是位指令?
答:伪指令(Pseudo instruction)是用于告诉汇编程序如何进行汇编的指令。它既不控制机器的操作也不被汇编成机器代码,
只能为汇编程序所识别并指导汇编如何进行。
1.LDR 大范围的地址读取伪指令(当有=号时为伪指令)
LDR 伪指令将一个32位的常数或者一个地址值读取到寄存器中。
语法格式
LDR{cond} register,={expr | label -expr}
其中,cond为可选的指令执行条件
register 为目标寄存器
expr 为32位的常量。编译器将根据expr的取值情况,决定如果处理LDR指令
①当expr表示的地址值没有超过MOV或MVN指令中的地址取值范围时,编译器用适当的MOV或MVN指令翻译LDR 指令
②当expr表示的地址值超过了MOV或者MVN指令中的地址取值范围时,编译器将该常数放在数据缓冲区中,同时用一条
基于PC的LDR指令读取该常数
也就是说,LDR伪指令要么翻译为MOV指令,要么翻译为LDR指令
label -expr为基于PC的地址表达式或者是外部表达式
①当label -expr为基于PC的地址表达式时,编译器将label -expr表示的数值放在数据缓冲区中,同时用一条基于PC的
LDR指令读取该数值
②当label -expr为外部表达式,或者非当前段的表达式时,汇编编译器将在目标文件中插入连接重定位伪操作,这样链
接器将在链接时生成该地址
使用说明
LDR伪指令主要有以下两种用途
①当需要读取到寄存器中的数据超过了MOV或MVN指令可以操作的范围时,可以使用LDR伪指令将数据读取到该寄存器中
②将一个基于PC的地址值或者外部的地址值读取到寄存器中。由于这种地址是在链接时确定的,所以这种代码不是位置无关的。
同时LDR伪指令处的PC值到缓冲区中的目标数据所在的地址的偏移量要小于4KB
示例
例1 将0xff0读取到R1中
LDR R1,=0xff0 汇编后将会得到 MOV R1,0xff0
例2 将0xfff读取到R1中
LDR R1,=0xfff 汇编后将会得到 LCD R1,[PC,OFFSET_TO_LPOOL] ... LPOOL DCD 0xFFF
例3 将外部地址ADDR1读到R1中
LDR R1,=ADDR1 汇编后将会得到 LDR R1,[PC,OFFSET_TO_LPOOL] ... LPOOL DCD ADDR1
实验
1.在keil-MDK中编写如下代码
注:代码是下载到内存运行的,地址为0x3000,0000
AREA Init, CODE ,READONLY
ENTRY
_start
ldr r0,copy ;这里是ldr指令,用于获取copy标号对应地址的内容
ldr r0,=copy ;这里是ldr伪指令,用于获取copy标号的绝对地址
mov r1,r0
mov r1,r0
copy
mov r0,r0
mov r0,r0
test1
b test1 END
经过反汇编得到的结果如下
: ldr r0,copy
0x30000000 E59F0008 LDR R0,[PC,#0x0008];此处R0中装的值应为地址值为(PC值+0x0008)指向的内容,PC指针值为
;0x3000,0000 + 8,即地址值为0x3100,0010,内容为E1A00000 : ldr r0,=copy ;这是一条伪指令,这一条指令被翻译成了两条语句,一条是在END后
0x30000004 E59F0010 LDR R0,[PC,#0x0010];定义了一个变量值,另一条是读取这个变量值,地址为
: mov r1,r0 ;0x3000,0004 + 8 + 0x10 = 0x3000,001c 此工程的最后一条指令地
0x30000008 E1A01000 MOV R1,R0 ;址为0x3000,0018 ,即END其实并不表示汇编程序的结尾
: mov r1,r0
: copy ;在ARM汇编中,标号没有实际的意义
0x3000000C E1A01000 MOV R1,R0 ;注意这里,KEIL反汇编的一个缺陷,看了半天才看懂,copy标号的
: mov r0,r0 ;地址实际应为0x3000,0010,KEIL把copy 和上一条指令mov r1,r0连在
0x30000010 E1A00000 NOP ;一起进行翻译了
: mov r0,r0
: test1
0x30000014 E1A00000 NOP
: b test1
0x30000018 EAFFFFFE B 0x30000018
2.ADR(小范围的地址读取指令)
该指令将基于PC的地址值或者基于寄存器的地址值读取到寄存器中
语法格式
ADR{cond} register,expr
expr 为基于PC或者寄存器的地址表达式,其取值范围如下
①当地址值不是字对齐的,其取值范围为 -255 ~ 255
②当地址值是字对齐的,其取值范围为 -1020 ~ 1020
使用说明
在汇编程序处理源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或者SUB指令来实现
该伪指令的功能。
如果不能用一条指令来实现ADR伪指令的功能,编译器将报错
因为ADR伪指令中的地址基于PC或者基于寄存器的,所以ADR读取到的地址为位置无关的地址。当ADR伪指令中的地址是基
于PC时,该地址与ADR伪指令必须在同一代码段中
示例
start
MOV r0,# ; 因为PC值为当前指令地址加8字节
ADR r4,start ; 本ADR伪指令将被编译替换成 SUB r4,pc,#0xc
实验
AREA Init, CODE ,READONLY
ENTRY
_start
adr r0,copy
mov r1,r0
mov r1,r0
copy
mov r0,r0
mov r0,r0
test1
b test1 END
经过反汇编后
: adr r0,copy
0x30000000 E28F0004 ADD R0,PC,#0x00000004 ;R0 = 0x3000,0000 + 8 + 0x04 = 0x3000000c,正好是copy标号的地址
: mov r1,r0
0x30000004 E1A01000 MOV R1,R0
: mov r1,r0
: copy
0x30000008 E1A01000 MOV R1,R0
: mov r0,r0
0x3000000C E1A00000 NOP
: mov r0,r0
: test1
0x30000010 E1A00000 NOP
: b test1
0x30000014 EAFFFFFE B 0x30000014
LDR 和 ADR 彻底详解的更多相关文章
- Linux内核异常处理体系结构详解(一)【转】
转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...
- 【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 : -- u-boo ...
- 【STM32H7教程】第13章 STM32H7启动过程详解
完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第13章 STM32H7启动过程详解 本章教 ...
- linux-2.6.26内核中ARM中断实现详解(转)
转载:http://www.cnblogs.com/leaven/archive/2010/08/06/1794293.html 更多文档参见:http://pan.baidu.com/s/1dDvJ ...
- 第14章 启动文件详解—零死角玩转STM32-F429系列
第14章 启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ...
- uboot配置和编译过程详解【转】
本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version ...
- [转]C语言字节对齐问题详解
C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...
- ARM Cortex-M底层技术(2)—启动代码详解
杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
随机推荐
- VS发布网站详细步骤
1.打开你的VS2012网站项目,右键点击项目>菜单中 重新生成一下网站项目:再次点击右键>发布: 2.弹出网站发布设置面板,点击<新建..>,创建新的发布配置文件: 输入你自 ...
- 2016 小马哥 IOS
2016 小马哥 IOS 最新视频完整版 链接:http://pan.baidu.com/s/1c1EQlBM 密码:mxkt
- adobe pro破解说明
安装说明(仔细阅读!)1.在安装之前手工修改host文件的方法:在hosts文件(默认位置C:\windows\system32\drivers\etc\hosts)中添加如下几行# Adobe Bl ...
- Multi-line NSAttributedString with truncated text
http://stackoverflow.com/questions/7611816/multi-line-nsattributedstring-with-truncated-text/1017279 ...
- ab压力测试和CC预防
这两天从服务器上拉数据时,发现取回的数据不正确,而客户端当初健壮性不强,导致解析的数据为空. 起初以为是服务器维护的问题,可今天服务器登陆上了,发现还是数据不正确,正好昨天数据部的哥们告诉了我一个比较 ...
- 几个与特殊字符处理有关的PHP函数
函数名 释义 介绍 htmlspecialchars 将与.单双引号.大于和小于号化成HTML格式 &转成&"转成"' 转成'<转成<>转成> ...
- How to Call SharePoint 2013 API Service to Query The Lists
How to Call SharePoint 2013 API In SharePoint 2013, we can query the list by it owner service, then ...
- iOS 直播(一)
由于业务需求,需要从腾讯直播sdk要迅速转移到自主开发(先让我默哀三分钟).不多说,直接开始唠嗑! 这个项目超级简单,简单到只能一个推流,一个拉流的功能.需求多的再另谈. 前期准备:推流用优酷开源的L ...
- Cocoapods降低版本及卸载
有的时候我们需要降低Cocoapods的版本来解决第三方库的兼容问题. 一. 移除pod组件 这条指令会告诉你Cocoapods组件装在哪里 : 1 $ which pod 你可以手动移除 ...
- Mac OS X Yosemite安装盘U盘制作
从App Store下载Mac OS X Yosemite安装程序,下载后的安装文件保存在应用程序(/Applications)文件夹中.请注意,此时一定不要直接启动该程序安装 OS X Yosemi ...