LDR指令、LDR伪指令、ADR伪指令区别

stm32学习笔记-启动文件 1、配置栈 Stack_Size EQU 0x00000400 AREA STACK, NOINIT, READWRITE, ALIGN=3 Stack_Mem SPACE Stack_Size __initial_sp EQU:相当于C中的define,定义Stack_Size = 0x00000400。 AREA: 指... 阅读详情

引例如下:

        先看一段代码:

        AREA test,CODE,READONLY
                 ENTRY

         ldr r0,__main
               adr r0,__main
               ldr r0,=__main
               nop       

      __main
               nop
               END

  反汇编一下后

  编译环境:realview 4.12 

  编译的时候设置   ROM1 :start_addr 0x30000000  、size   0x200000  

          RAM1 :start_addr 0x30200000  、 size:0x4000000 

  下面是反汇编的结果:

\\   code        pc_current    binary   code after asmcc

  6: ldr r0,__main     0x300000D8  E59F0008   LDR       R0,[PC,#0x0008]    

  7: adr r0,__main    0x300000DC  E28F0004   ADD      R0,PC,#0x00000004    

  8: ldr r0,=__main   0x300000E0  E59F0004   LDR       R0,[PC,#0x0004]          

  9: nop     

  10:      

  11: EXPORT __main     

  12: __main        0x300000E4  E1A00000   NOP           

  13: b __main     0x300000E8  EAFFFFFE    B         0x300000E8

               0x300000EC  300000E8   ANDCC     R0,R0,R8,ROR #1

  下面来分析一下这三条指令

  1、ldr r0,__main    ;这条指令实现将__main位置中的值装入r0中

    经过汇编后,__main将被一个相对于PC的表达式取代

    __main =>  [pc,#4]   ;应为arm指令是以三级流水线的执行,pc=pc_current+0x08   所以最后地址(pc+4)中的值装入r0中

    总结:ldr r0, __main是根据__main对PC(pc_current+8)的相对位置(+4)读取其所在地址的值,因此可以在和___main标号的相对位置不变的情况下移动。

  2、adr r0,__main       ;小范围的地址读取伪指令

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

    在这里是取得标号__main 的地址到 r0,因为地址是相对程序的,因此ADR产生依赖于位置的代码。

    本例中会变成:ADD      R0,PC,#0x00000004  。因此该代码可以在和标号相对位置不变的情况下移动。假如:这段代码在 0x30000000 运行,那么 adr r0, __main得到 r0 = 0x3000000c;如果在地址 0 运行,就是 0x0000000c 了。

  3、ldr r0,=__main        ;大范围的地址读取

    LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。这个指令取得标号 __main 的绝对地址,这个绝对地址是在 link 的时候确定的,看上去这只是一个指令,但是它要占用 2 个 32bit 的空间,一条是指令,另一条是 __main 的数据(因为在编译的时候不能确定 __main的值,而且也不能用 mov 指令来给 r0 赋一个 32bit 的常量,所以需要多出一个空间存放 __main 的真正数据,在这里就是 0x300000EC这个地址,取其中的值300000E8 )。

    因此可以看出,这个是绝对的寻址,不管这段代码在什么地方运行,它的结果都是 r0 = 300000E8 。

 

  完整的总结一下吧:

1、ADR伪指令--- 小范围的地址读取

     ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

    ADR伪指令格式 :ADR{cond}   register, expr  

      地址表达式expr的取值范围:

          当地址值是字节对齐时,其取指范围为: +255 ~ 255B;

          当地址值是字对齐时,其取指范围为:   -1020 ~ 1020B;

2、ADRL伪指令----中等范围的地址读取

    ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。

  在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。

    ADRL伪指令格式:ADRL{cond}   register, expr

      地址表达式expr的取值范围:

          当地址值是字节对齐时,其取指范围为: -64K~64K;

         当地址值是字对齐时,其取指范围为:   -256K~256K;

3、LDR伪指令-----大范围的地址读取

    LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。

  若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。

 

 

====

http://www.cnblogs.com/jack739x/articles/2060762.html

STM32 __main汇编分析 _main的汇编级调用在启动文件中表现为简单的地址跳转(LDRBX),但其内部逻辑由编译器自动生成,负责初始化C程序的运行时环境。通过调试器反汇编和内存观察,可间接验证其行为逻辑。 阅读详情

相关推荐

__main代码分析

STM32启动代码主要是分配堆栈及设置向量表,然后跳转到__main函数。 跳转具体到代码段部分如下: [cpp] view plain copy Reset_Handler   PROC                   EXPORT  Reset_Handler             [WEAK]                

lushoumin的博客 7910

MDK __main()代码执行分析

__main()代码执行分析 以keyled程序为例说明,keyled代码请参考我的博客网址:http://my.youkuaiyun.com/wfq0624/code/detail/7645   程序经过汇编启动代码,执行到__main()后,可以看出有两个大的函数: __scatterload():负责把RW/RO输出段从装载域地址复制到运行域地址,并完成了ZI运行域的初始化工作。

tianshi_1988的专栏 1万+

2024最新超详细无痛安装PyTorch,包括下载地址、环境配置与各种避坑指南

PyTorch更新很快,2024最新下载安装经验贴,包括anaconda+CUDA+cuDNN+PyTorch四部分的下载和安装。文章详细介绍了下载地址、环境配置、虚拟环境建立的问题,还温馨提示了各种闭坑指南。有需要的友友快过来康康!

qq_43596278的博客 11万+

STM32 启动解析__main main

在启动文件我们看到了__main和用户写的main,这2个是有区别的,大概流程如下: 1、复位第一条指令:Reset_Handler PROC,这里指定为 LDR R0, =__main。表示调用库函数__main,当然,我们可以在__main前做点事情,比如PLL初始化等。 2、__main()的执行流程参考: 跟一下汇编,大概是__scatterload()->__rt_entry()->__user_setup_stackheap() 3、最后调用用户的main()函数。 4、...

weiyaonan的专栏 3590

【Oracle数据库】Oracle11g数据库下载与安装教程(超详细安装图解)

Oracle11g是Oracle公司出的一个比较轻量版的数据库,这里重点说一下在window系统上如何安装Oracle11g, Oracle11g是很早之前的安装包,win7 系统安装时不会遇到环境不满足最低要求的提示,win11系统安装时会提醒环境不满足,修改配置文件即可(注意:先安装oracle服务端/oracle客户端,再安装第三方工具(PL/ SQL Developer,DBeaver等)服务器端环境概述:ORACLE数据库版本:Oracle 11g 64位(11.2.0)

qq_34463511的博客 1万+

Delphi 12.3 精简绿色版下载

Delphi精简绿色版基于原版安装,去掉了InterBase、法语、德语、日语,只保留了Delphi Windows 32和Delphi Windows 64桌面开发,其余部分未做任何修改。Delphi精简绿色版不含任何破解,仅供学习和研究,24小时后请自行删除,如需继续使用Delphi,请购买正版。绿色版基于原版安装,未做任何精简和修改。绿色版不含任何破解,仅供学习和研究,24小时后请自行删除,如需继续使用RAD Studio,请购买正版。

全粘工程师 4294

伪指令ADR和LDR的区别

1、一个事实:大部分指令是位置有关编码     a、位置无关编码(PIC,position independent code):汇编源文件被编码成二进制可执行程序时编码方式与位置(内存地址)无关。     b、位置有关编码:汇编源码编码成二进制可执行程序后和内存地址是有关的。        我们在设计一个程序时,会给这个程序指定一个运行地址(链接地址)。就是说我们在编译程

墨的博客 2656

网络摄像头(IPC)介绍:类型、供电、镜头、夜视等

IPC(Internet Protocol Camera,网络摄像头),它是一种由传统摄像机与网络技术结合所产生的新一代摄像机。它可以将视频、音频、报警及控制信号通过网络传输,接受网络监控主机(NVR或监控管理平台)的管理。IPC可与路由器、交换机、NVR等设备组建成为监控系统。

学无止境,Fighting! 1万+

[ARM]ldr 和 adr 伪指令的区别

一.首先熟悉几个arm地址相关的概念:首先arm地址有三个地址概念:编译地址、期望运行物理地址、实际运行物理地址、相对地址、绝对地址、位置无关编译地址:编译阶段的生成地址,其是相对地址,有些地址还没确定,如调用其他.O文件中的函数或库函数期望运行物理地址:链接阶段生成的地址(期望绝对地址),

HK836的专栏 1510

5分钟搞懂双目相机标定:从棋盘格到3D点云的完整流程(附Python代码)

本文详细介绍了双目相机标定的完整流程,从棋盘格准备到3D点云生成,涵盖单目标定、双目标定、立体校正、视差计算等关键步骤。通过Python代码示例,帮助读者快速掌握双目立体视觉技术,实现高精度的3D重建。特别适合机器人导航、工业检测等应用场景。

weixin_29100399的博客 585

Unity技能系统核心:从理论到实践构建可扩展的Buff管理器

本文深入探讨了Unity游戏开发中构建可扩展技能系统的核心——Buff管理器。通过剖析三层架构(数据、逻辑、渲染)与独立组件管理模式,提供了从Buff数据定义、管理器核心实现到可视化编辑器搭建的完整实践方案,旨在解决技能系统维护难题,提升开发效率与代码质量。

weixin_29002209的博客 253

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

ARM汇编语言中有ldr指令和ldr、adr伪指令,他们都可以将标号表达式作为操作数。区别如下: ldr指令和adr、ldr伪指令的区别:ldr指令属于load-store指令,用于读取标号地址中的值;adr、ldr伪指令用于获取标号的地址。 adr和ldr伪指令的区别:adr是获取相对PC的地址,与程序当前运行的位置相关,是小范围的地址读取伪指令;ldr是获取绝对地址,绝对地址是在l

学习是为了探索这个世界的本质 1476

高数15种常见特殊曲线:星形线、心形线、摆线、对数螺线、双曲螺线、阿基米德螺线、伯努利双纽线、三叶玫瑰线、四叶玫瑰线、六叶玫瑰线、三次抛物线、半立方抛物线、箕舌线、蔓叶线、笛卡儿叶形线、概率曲线

4.1 对数螺线(等角螺线、生长螺线)三叶玫瑰线、四叶玫瑰线、六叶玫瑰线。​7.2 半立方抛物线(尼尔曲线)10.笛卡儿叶形线(茉莉花瓣曲线)常考选择题、填空题,大题也涉及。​4.2 双曲螺线(倒数螺线)11.阿基米德螺线(等速螺线)3.摆线(圆滚线、旋轮线)5.双纽线(伯努利双纽线)1.星形线(四尖瓣线)2.心形线(心脏线)..................

刘鑫磊 1万+

8.adr与ldr伪指令的区别

8.adr与ldr伪指令的区别 ldr和adr都是伪指令,区别是ldr是长加载、adr是短加载。 重点:adr指令加载符号地址,加载的是运行时地址; ldr指令加载符号地址时,加载的是链接地址。 posted on 2016-09-12 16:22 Sch...

weixin_30724853的博客 177

基于STM32单片机的智能分拣系统

基于STM32单片机的智能分拣系统是一种高效、精准的自动化分拣解决方案,适用于物流、仓储、制造业等领域。该系统利用STM32单片机作为核心控制器,结合传感器技术、电机控制算法和通信模块,实现对物品的自动识别、分类和分拣。通过智能化的设计,该系统能够大幅提高分拣效率,降低人工成本,并减少错误率。基于STM32单片机的智能分拣系统是一种高效、精准、低成本的自动化解决方案,能够广泛应用于物流、制造、环保等领域。

qq_62634009的博客 1939

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

LDR伪指令和ADR指令的区别

其中 0xfd8000000000 是在链接器脚本中指定的虚拟地址,改地址是通过 ldr 伪指令从内存中读取出来的,如果使用 adr 指令是不可以的,偏移超过了指令的范围,adr 获取的地址与当前 PC 有关系,此时运行在物理地址空间,所以 adr 得到的是物理地址。要求 label 和 $PC 位置在 正负1MB的范围内(这个数值和上面提到的imm有关)看 Operation 即可看出作用,Xd 赋值为 $PC + imm。

jingyu_1的博客 575

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

LDR与ADR伪指令的区别

在学习ARM汇编指令的时候,经常会使用到ldr与adr两条指令,相信大部分初学的人曾经都对这两个命令产生过疑惑。其实这两条指令都是伪指令: ldr是大范围的读取地址伪指令,相当于PC寄存器或其他寄存器的长跳转; adr指令时小范围的地址读取伪指令,相对于PC寄存器或其他寄存器的小范围跳转。 要想清楚的说明这两条指令的区别,还是得从实际的例子中来解释,空谈泛泛,难以实际掌握。 ldr r0, _

yanlinembed的专栏 1085

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

[ARM]ldr和 adr/adrl 伪指令的区别

一.首先熟悉几个arm地址相关的概念: 首先arm地址有三个地址概念:编译地址、期望运行物理地址、实际运行物理地址、相对地址、绝对地址、位置无关 编译地址 :编译阶段的生成地址,其是相对地址 ,有些地址还没确定,如调用其他.O文件中的函数或库函数 期望运行物理地址:链接阶段生成的地址(期望绝对地址),会确定编译阶段没有确定的地址,并会根据链接器假设期望的程序烧录运行物理启始地

wushui2的博客 586

ldr和 adr/adrl 伪指令的区别

一.首先熟悉几个arm地址相关的概念: 首先arm地址有三个地址概念:编译地址、 期望运行物理地址、实际运行物理地址、相对地址、绝对地址、位置无关 编译地址 :编译阶段的生成地址,其是相对地址 ,有些地址还没确定,如调用其他.O文件中的函数或库函数 期望运行物理地址 :链接阶段生成的地址(期望绝对地址 ),会确定编译阶段没有确定的地址,并会根据链接器假设期望的程序烧录运行物理

Android移动开发者 1328

伪指令 ADR 与 LDR 的区别

指令简介: adr r0, _start 得到的是 _start 的当前执行位置,由 pc+offset 决定 ldr r0, =_start 得到的是绝对的地址,链接时决定 程序示例: ldr r0, _start adr r0, _start ldr r0, =_start nop mov pc, lr _start: nop 下面是反汇编的结果: 0c008...

aiduan6474的博客 134

[转][ARM]ldr和 adr/adrl 伪指令的区别

一.首先熟悉几个arm地址相关的概念: 首先arm地址有三个地址概念:编译地址、 期望运行物理地址、实际运行物理地址、相对地址、绝对地址、位置无关编译地址 :编译阶段的生成地址,其是相对地址 ,有些地址还没确定,如调用其他.O文件中的函数或库函数期望运行物理地址 :链接阶段生成的地址(期望绝对地址 ),会确定编译阶段没有确定的地址,并会根据链接器假设期望的程序烧录运行物理启始地址 ,来分配期望运...

weixin_30950607的博客 219
上一篇: u-boot编译过程理解
下一篇: u-boot的内存分布和全局数据结构
Alan0521
博客等级 码龄19年 77粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值