热门标签 | HotTags
当前位置:  开发笔记 > 程序员 > 正文

ARM中的ldr指令与adr、ldr伪指令之间的区别

ARM汇编语言中有ldr指令和ldr、adr伪指令,他们都可以将标号表达式作为操作数。区别如下:ldr指令和adr、ldr伪指令的区别:ldr指令属于load-store指令,用于读取标号地址中的&

 ARM汇编语言中有ldr指令和ldradr伪指令,他们都可以将标号表达式作为操作数。区别如下:

ldr指令和adrldr伪指令的区别:ldr指令属于load-store指令,用于读取标号地址中的值;adrldr伪指令用于获取标号的地址。

adrldr伪指令的区别:adr是获取相对PC的地址,与程序当前运行的位置相关,是小范围的地址读取伪指令;ldr是获取绝对地址,绝对地址是在link的时候确定的,它与程序当前运行位置无关,是大范围读取地址伪指令。

下面通过分析一段代码以及对应的反汇编接过来说明他们的区别。

       ldr r0,_start

       adr r0,_start

       ldr r0,=_start

_start:

       b _start

       编译的时候设置r00x30000000,下面是反汇编的结果:

0x00000000:e59f0004   ldr r0,[pc,#4]    ;0xc

0x00000004:e28f0000   add r0,pc,#0     ;0x0

0x00000008:e59f0000   ldr r0,[pc,#0]    ;0x10

0x0000000c:eafffffe     b  0xc

0x00000010:3000000c   andcc r0,r0,ip

       1.ldr r0,_start

       这是一条指令,从内存地址_start的位置装载该地址存放的数据。

       在这里_start是一个标号(是一个相对程序的表达式),汇编程序计算相对于PC的偏移量,并生成相对于PC的前索引的指令:ldr r0,[pc,#4]。指令执行后,r0=0xeafffffe(计算方法:r0 = [pc(0x00000000+8)+4]= [0x0000000c] = 0xeafffffe)。

       ldr r0,_start是根据_start对当前PC的相对位置读取其所在地址的值,因此可以在和_start标号的相对位置不变的情况下获取数据值。

       2.adr r0,_start

       这是一条伪指令,总是会被汇编程序会变为一个指令,汇编程序尝试产生单个ADDSUB指令来装载该地址。如果不能在一个指令中构造该地址,则生成一个错误,并且汇编失败。

       这里是取得标号_start的地址到r0,因为地址是相对程序的,因此adr的产生依赖于位置的代码,在此例中被汇编成:add r0,pc,#0。因此该代码可以在和标号相对位置不变的情况下移动。

       假如这段代码在0x30000000运行,那么adr r0,_start得到r0 = 0x3000000c;如果在地址0运行,那么就是0x0000000c了。

       通过这一点可以判断程序在什么地方运行。U-Boot中那段relocate代码就是通过adr实现当前程序是在RAM中还是FLASH中。

       3.ldr r0,=_start

       这是一条伪指令,_start是一个绝对地址(也即运行地址)。这个绝对地址是在链接的时候确定的,它占用232bit的空间,一条是指令,另一条是文字池中存放_start的绝对地址。在此例中生成的指令为:ldr r0,[pc,#0],对应文字池中的地址以及值为:0x00000010:3000000c,因此该伪指令执行后r0的值为0x3000000c。因此可以看出,不管这段代码将来在什么地方运行,它的结果都是r0=0x3000000c

       由于ldr r0,=_start取得的是_start的绝对地址,这句代码可以在_start标号的绝对位置不变的情况下移动,如使用寄存器pc在程序中可以实现绝对转移。


推荐阅读
  • 解析SQL查询结果的排序问题及其解决方案
    本文探讨了为什么某些SQL查询返回的数据集未能按预期顺序排列,并提供了详细的解决方案,帮助开发者理解并解决这一常见问题。 ... [详细]
  • 尽管深度学习带来了广泛的应用前景,其训练通常需要强大的计算资源。然而,并非所有开发者都能负担得起高性能服务器或专用硬件。本文探讨了如何在有限的硬件条件下(如ARM CPU)高效运行深度神经网络,特别是通过选择合适的工具和框架来加速模型推理。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 解决PHP与MySQL连接时出现500错误的方法
    本文详细探讨了当使用PHP连接MySQL数据库时遇到500内部服务器错误的多种解决方案,提供了详尽的操作步骤和专业建议。无论是初学者还是有经验的开发者,都能从中受益。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 解读MySQL查询执行计划的详细指南
    本文旨在帮助开发者和数据库管理员深入了解如何解读MySQL查询执行计划。通过详细的解析,您将掌握优化查询性能的关键技巧,了解各种访问类型和额外信息的含义。 ... [详细]
  • 本文详细介绍了macOS系统的核心组件,包括如何管理其安全特性——系统完整性保护(SIP),并探讨了不同版本的更新亮点。对于使用macOS系统的用户来说,了解这些信息有助于更好地管理和优化系统性能。 ... [详细]
  • Google最新推出的嵌入AI技术的便携式相机Clips现已上架,旨在通过人工智能技术自动捕捉用户生活中值得纪念的时刻,帮助人们减少照片数量过多的问题。 ... [详细]
  • 本文深入探讨了 Java 编程语言的基础,特别是其跨平台特性和 JVM 的工作原理。通过介绍 Java 的发展历史和生态系统,帮助初学者理解如何编写并运行第一个 Java 程序。 ... [详细]
  • 本文详细记录了在银河麒麟操作系统和龙芯架构上使用 Qt 5.15.2 进行项目打包时遇到的问题及解决方案,特别关注于 linuxdeployqt 工具的应用。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 2022年单片机课程(机器人工程)教学反思
    本文对2022年单片机类课程的教学进行了全面反思,分析了教学过程中遇到的问题,并探讨了未来改进的方向。 ... [详细]
author-avatar
松恋崖
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有