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 彻底详解的更多相关文章

  1. Linux内核异常处理体系结构详解(一)【转】

    转自:http://www.techbulo.com/1841.html 2015年11月30日 ⁄ 基础知识 ⁄ 共 6653字 ⁄ 字号 小 中 大 ⁄ Linux内核异常处理体系结构详解(一)已 ...

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

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42462795 转载请著名出处 相关资源下载 :  -- u-boo ...

  3. 【STM32H7教程】第13章 STM32H7启动过程详解

    完整教程下载地址:http://forum.armfly.com/forum.php?mod=viewthread&tid=86980 第13章       STM32H7启动过程详解 本章教 ...

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

    转载:http://www.cnblogs.com/leaven/archive/2010/08/06/1794293.html 更多文档参见:http://pan.baidu.com/s/1dDvJ ...

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

    第14章     启动文件详解 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/firege ...

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

    本文转载自:http://blog.csdn.net/czg13548930186/article/details/53434566 uboot主Makefile分析1 1.uboot version ...

  7. [转]C语言字节对齐问题详解

    C语言字节对齐问题详解 转载:https://www.cnblogs.com/clover-toeic/p/3853132.html 引言 考虑下面的结构体定义: typedef struct{ ch ...

  8. ARM Cortex-M底层技术(2)—启动代码详解

    杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第 ...

  9. Linq之旅:Linq入门详解(Linq to Objects)

    示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...

随机推荐

  1. Andorid开发学习---ubuntu 12.04下搭建超好用的安卓模拟器genymotion 安装卸载virtualbox 4.3

    什么是Genymotion? Genymotion是一套完整的工具,它提供了Android虚拟环境.它简直就是开发者.测试人员.推销者甚至是游戏玩家的福音. Genymotion支持Windows.L ...

  2. css3新属性@ text-shadow

    text-shodow是css3的新属性,可以利用这个属性使字体更有立体感,还可以创造有趣的效果. 1.语法形式:text-shadow : x-offset(x轴偏移量) y-offset(y轴偏移 ...

  3. OOP

    class Worker(object): def __init__(self,name,bu,score,sex,age): self.__name = name self.__bu = bu se ...

  4. yield学习续:yield return迭代块在Unity3D中的应用——协程

    必读好文推荐: Unity协程(Coroutine)原理深入剖析 Unity协程(Coroutine)原理深入剖析再续 上面的文章说得太透彻,所以这里就记一下自己的学习笔记了. 首先要说明的是,协程并 ...

  5. 【11_83】Remove Duplicates from Sorted List

    这道题本质上不难,难的是细节处理,容易出错. 第一遍写的代码越改越大,越臃肿,此时,不如推倒重写,果然,第二次一遍过. Remove Duplicates from Sorted List My Su ...

  6. keil 的头文件 .

    许多初学者使用网上下载的程序时都会遇到这样一个问题,就是头文件找不到.我想就这个问题说明一下./·首先,我们用到的KEIL有几种版本的,头文件也不同.有reg51.h和at89x51.h两种比较常见. ...

  7. struts2的运行原理及配置文件

    struts2官方运行原理图: 1,客户发送请求(url地址就是请求),tomcat接到请求会找到相应的应用web.xml配置文件. 2,web.xml中filter拦截器把你的请求接收到,并进入Fi ...

  8. Android:res之layer-list的用法

    layer-list可以将多个图片按照顺序层叠起来,让其看起来像一个图一样.  和    叠加为: 用法: 在在drawable下建立一个xml文件,faceleft.xml <?xml ver ...

  9. 【转载】-- vi/vim使用

    vi/vim 基本使用方法本文介绍了vi (vim)的基本使用方法,但对于普通用户来说基本上够了!i/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim 是vi的升级版本,它不仅兼容vi的所 ...

  10. 关于X锁的问题--由select+X锁是否持有到事务结束的误区

    前言:看了宋桑的文章<一次意外的X锁不阻塞问题>,结合本人的测试,说明一下我对select中使用X锁是否会持有到事务结束产生的误区: 详情不多说了,详见宋桑的<一次意外的X锁不阻塞问 ...