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

 1     AREA Init, CODE ,READONLY
 2     ENTRY
 3 _start
 4     ldr r0,copy   ;这里是ldr指令,用于获取copy标号对应地址的内容
 5     ldr r0,=copy  ;这里是ldr伪指令,用于获取copy标号的绝对地址
 6     mov r1,r0
 7     mov r1,r0
 8 copy
 9     mov r0,r0
10     mov r0,r0
11 test1
12     b test1
13
14     END

经过反汇编得到的结果如下

 1      4:     ldr r0,copy
 2 0x30000000  E59F0008  LDR       R0,[PC,#0x0008];此处R0中装的值应为地址值为(PC值+0x0008)指向的内容,PC指针值为
                                                  ;0x3000,0000 + 8,即地址值为0x3100,0010,内容为E1A00000

 3      5:     ldr r0,=copy                       ;这是一条伪指令,这一条指令被翻译成了两条语句,一条是在END后
 4 0x30000004  E59F0010  LDR       R0,[PC,#0x0010];定义了一个变量值,另一条是读取这个变量值,地址为
 5      6:         mov r1,r0                      ;0x3000,0004 + 8 + 0x10 = 0x3000,001c  此工程的最后一条指令地
 6 0x30000008  E1A01000  MOV       R1,R0          ;址为0x3000,0018 ,即END其实并不表示汇编程序的结尾
 7      7:         mov r1,r0
 8      8: copy                                   ;在ARM汇编中,标号没有实际的意义
 9 0x3000000C  E1A01000  MOV       R1,R0          ;注意这里,KEIL反汇编的一个缺陷,看了半天才看懂,copy标号的
10      9:     mov r0,r0                          ;地址实际应为0x3000,0010,KEIL把copy 和上一条指令mov r1,r0连在
11 0x30000010  E1A00000  NOP                      ;一起进行翻译了
12     10:         mov r0,r0
13     11: test1
14 0x30000014  E1A00000  NOP
15     12:     b test1
16 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伪指令必须在同一代码段中

示例

1 start
2     MOV r0,#10     ; 因为PC值为当前指令地址加8字节
3     ADR r4,start   ; 本ADR伪指令将被编译替换成 SUB r4,pc,#0xc

实验

 1     AREA Init, CODE ,READONLY
 2     ENTRY
 3 _start
 4     adr r0,copy
 5     mov r1,r0
 6     mov r1,r0
 7 copy
 8     mov r0,r0
 9     mov r0,r0
10 test1
11     b test1
12
13     END

经过反汇编后

     4:     adr r0,copy
0x30000000  E28F0004  ADD       R0,PC,#0x00000004  ;R0 = 0x3000,0000 + 8 + 0x04 = 0x3000000c,正好是copy标号的地址
     5:         mov r1,r0
0x30000004  E1A01000  MOV       R1,R0
     6:         mov r1,r0
     7: copy
0x30000008  E1A01000  MOV       R1,R0
     8:     mov r0,r0
0x3000000C  E1A00000  NOP
     9:         mov r0,r0
    10: test1
0x30000010  E1A00000  NOP
    11:     b test1
0x30000014  EAFFFFFE  B         0x30000014
时间: 2024-08-25 04:47:55

LDR 和 ADR 彻底详解的相关文章

ARM LDR伪指令用法详解

LDR伪指令 10.45 LDR pseudo-instruction   功能:把一个32位立即数或一个32位的内存地址加载到一个寄存器中. 注意:这里描述的是LDR伪指令,而不是LDR指令   语法:               LDR{cond}{.W} Rt, =expr LDR{cond}{.W} Rt, =label_expr *   cond是一个可选的条件码 *  .W是可选的指令宽度说明符 *   Rt是要加载的寄存器 *   expr是一个数字表达式 *   label_ex

windbg命令详解

DLL 该扩展仅在内核模式下使用,即使它是在Ext.dll中的. Windows NT 4.0 Ext.dll Windows 2000 Ext.dll Windows XP和之后 Ext.dll 注释 如果不提供参数,调试器会列出所有进程,以及时间和优先级统计.这和使用!process @#Process 0 作为CommandString值一样. To terminate execution at any point, press CTRL+BREAK (in WinDbg) or CTRL

【嵌入式开发】 Bootloader 详解 ( 代码环境 | ARM 启动流程 | uboot 工作流程 | 架构设计)

作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boot 源码 : http://download.csdn.net/detail/han1202012/8342761 -- S3C2440 文档 : http://download.csdn.net/detail/han1202012/8342701 -- S5PV210_iROM_Applicati

Oracle 12c Cluster Health Monitor 详解

注:本文谢绝转载! 1  CHM 概述 Cluster HealthMonitor 会通过OS API来收集操作系统的统计信息,如内存,swap 空间使用率,进程,IO 使用率,网络等相关的数据. CHM 的信息收集是实时的,在11.2.0.3 之前是每1秒收集一次,在11.2.0.3 之后,改成每5秒收集一次数据,并保存在CHM 仓库中. 这个收集时间间隔不能手工修改. CHM 的目的也是为了在出现问题时,提供一个分析的依据,比如节点重启,hang,实例被驱逐,性能下降,这些问题都可以通过对C

linux-2.6.26内核中ARM中断实现详解(转)

转载:http://www.cnblogs.com/leaven/archive/2010/08/06/1794293.html 更多文档参见:http://pan.baidu.com/s/1dDvJRaD 作者:刘洪涛,华清远见嵌入式学院金牌讲师,ARM ATC授权培训讲师. 看了一些网络上关于linux中断实现的文章,感觉有一些写的非常好,在这里首先感谢他们的无私付出,然后也想再补充自己对一些问题的理解.先从函数注册引出问题吧. 一.中断注册方法 在linux内核中用于申请中断的函数是req

第14章 启动文件详解—零死角玩转STM32-F429系列

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册—ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是

uboot配置和编译过程详解【转】

本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version确定(Makefile的24-29行) Makefile代码部分: [plain] view plain copy VERSION = 1 PATCHLEVEL = 30 SUBLEVEL = 4 EXTRAVERSION = U_BOOT_VERSION = $(VERSION).$(PATCHL

(3)uboot详解——饿了么,我们来喂“狗”吧

(3)uboot详解--饿了么,我们来喂"狗"吧 uboot启动时,当将cpu运行模式设置为管理模式后,就要关闭看门狗了,那么看门狗是干什么的呢? 狗狗是我们的好朋友,有时候,一条好狗狗能够救主人的性命,"看门狗"是cpu的"好朋友",它也能够在cpu出状况的时候把它救活. 看门狗其实就是一个可以在一定时间内被复位的计数器,当看门狗启动后,计数器开始自动计数,经过一定时间,cpu就会将这个计数器复位,如果没有被复位,计数器溢出就会对CPU产生一个

第14章 启动文件详解

第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege 本章参考资料<STM32F4xx 中文参考手册>第十章-中断和事件:表 46. STM32F42xxx 和 STM32F43xxx 的向量表:MDK中的帮助手册-ARM Development Tools:用来查询ARM的汇编指令和编译器相关的指令. 14.1 启动文件简介 启动文件由汇编编写,是