zoukankan      html  css  js  c++  java
  • LDR伪指令与ADR伪指令的区别

    测试代码

             ldr     r0, _start
            adr     r0, _start
            ldr     r0, =_start
            nop
            mov     pc, lr
    _start:
            nop

       设置代码的起始地址为 0x0c008000,用 ADS1.2编译后的反汇编如下所示

    ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    
    0c008000 <_start-0x14>:
    c008000:       e59f000c        ldr     r0, [pc, #12]   ; c008014 <_start>
    c008004:       e28f0008        add     r0, pc, #8      ; 0x8
    c008008:       e59f0008        ldr     r0, [pc, #8]    ; c008018 <_start+0x4>
    c00800c:       e1a00000        nop                     (mov r0,r0)
    c008010:       e1a0f00e        mov     pc, lr
    
    0c008014 <_start>:
    c008014:       e1a00000        nop                     (mov r0,r0)
    c008018:       0c008014        stceq   0, cr8, [r0], -#80

    分析: 

    1、ldr     r0, _start

    从内存地址 _start(0c008014) 的地方把值读入。执行这个后,r0 = 0xe1a00000。

    2、adr     r0, _start

        通过指令“add     r0, pc, #8 ”把_start 的当前运行地址加载到 r0,它是与位置无关的。例如这段代码在 0x0c008000 运行,那么 adr r0, _start 得到 r0 = 0x0c008014;如果在地址 0 运行,就是 0x00000014 了。                                                                                                                                              

        那么通过这条伪指令就可以得知当前程序在内存的什么位置运行。这是一条伪指令,但是功能却如此强大,需要相应的编译器功能才能实现。

    3、ldr     r0, =_start

    这条指令取得的是标号_start 的绝对地址。这个绝对地址是在 link 的时候确定的。看上去这只是一个指令,但是它要占用 2 个 32bit 的空间,一条是指令,另一条是 _start 的数据(因为在编译的时候不能确定 _start 的值,而且也不能用 mov 指令来给 r0 赋一个 32bit 的常量,所以需要多出一个空间存放 _start 的真正数据,在这里就是 0x0c008014)。 

  • 相关阅读:
    no match for call to ‘(std::__cxx11::string {aka std::__cxx11::basic_string
    一转眼,已四年
    线程或进程绑定到特定的cpu
    微信好友信息统计-图、词云和热图
    微信聊天机器人-存储好友分享消息
    Qt之加减乘除四则运算-支持负数
    windows粘贴板操作-自己的应用和windows右键互动
    Qt之QDomDocument操作xml文件-模拟ini文件存储
    Qt之表格控件蚂蚁线
    Qt之移动硬盘热插拔监控
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3419710.html
Copyright © 2011-2022 走看看