• 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)。 

  • 相关阅读:
    Java设计模式
    Java复习,Java知识点以及Java面试题(七)
    Java复习,Java知识点以及Java面试题(六)
    Java复习,Java知识点以及Java面试题(五)
    Java复习,Java知识点以及Java面试题(四)
    Java复习,Java知识点以及Java面试题(三)
    Java复习,Java知识点以及Java面试题(二)
    代理模式
    String的花式比较
    spring配置shiro的案例学习笔记
  • 原文地址:https://www.cnblogs.com/amanlikethis/p/3419710.html
Copyright © 2020-2023  润新知