• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
cunning007
博客园    首页    新随笔    联系   管理    订阅  订阅

位置无关与有关跳转

重要的概念

1.链接地址:链接时指定的地址(指定方式:使用-Text,或者链接脚本)

   运行地址:程序实际运行时地址(指定方式:由实际运行时被加载到内存的哪个位置决定的)

   链接地址和运行地址:可能相同也可能不同

 加载地址:程序在存储器(NAND,NOR等)中的地址

2.位置无关码:赖于程序当前运行的PC值,进行相对的跳转(编译器自动找到目标地址相对于当前PC值的偏移量offset,相对于当前PC值去跳转),导致的结果就是,无论代码在哪,总能达到指令的正常目的,因此是位置无关的

   位置相关码:不依赖当前PC值,是绝对跳转,只有程序运行在链接地址处时(编译器根据链接脚本得到实际需要跳转目的的绝对地址),才能达到指令的正常目的,因此是位置有关系的

 

重要指令

1.位置无关跳转:B指令--B指令接受一个相对地址,在汇编里使用B跳转到一个标号时,实际编译结果是一个相对跳转。跳转范围不能太远,offset must in 32 Mbit

        BL指令--BL指令用于调用函数,是相对跳转,与B一样

        ADR指令--ADR指令获取标号地址,在编译时会使用PC+offset的方式得到该位置的地址

        LDR指令--LDR指令不加“=”时,表示位置无关跳转

2.位置相关跳转:LDR指令,LDR PC,=LABLE,相对跳转,与代码位置和链接地址相关,跳转到绝对地址

 

LDR指令的重要说明

LDR指令有如下三种使用方法,说明如下:

  1.LDR r1,#100   加载立即数到指定寄存器

  2.LDR r1,=label 将label标号的地址值存入指定寄存器

  3.LDR r1,label  将label地址中的值存入指定寄存器

 

实例说明

1.注:ARM9是3级流水线,也就是处理器处理时正在执行第1条指令的同时对第2条指令进行译码,并将第3条指令从存储器中取出,如下图所示,PC寄存器总是指向第3条指令取值的地方(就是说,处理器正在执行的是1号指令,PC寄存器的值是3号指令的地址值)

 

 

2.makefile

 

 

 

源码

 

反汇编

 

 

 

  (1)ldr r0,on_sdram ,反汇编是ldr r0,[PC,#4],由于当前指令地址是4,PC寄存器值为4+8,偏移量offset是4,所有指令会把4+8+4这个地址的值(也就是机器码e3a0d30d)存到r0(注意反汇编的[]中括号)。一般情况ldr r0,label的使用情形是 

  ldr r0,label

  label:

    .word 0x10000000

  把某个值放到寄存器里

  (2)ldr r0,=on_sdram,反汇编是ldr r0,[PC,#24],ldr r0,= label 反汇编是ldr没有“=”标号的ldr指令,编译器根据链接地址,在text代码段的末端空白地址存放目标地址值(如0x28 地址处的0x10,实际就是目标地址值)这样计算offset以得到绝对地址(这个偏移量offset编译器自动计算),实际就是把:当前运行地址 8 + PC寄存器地址8 + 偏移量#24 = 40(0x28),最后把0x28地址中的值0x10放到r0中。如果指令是ldr pc,=on_sdram ,就是把0x10放到PC寄存器中,这样实现了跳转。

 

 

 

 

 

以上,

2020/04/17

 

posted @ 2020-04-17 07:50  cunning007  阅读(307)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3