位置无关码介绍

2023-11-05

1. 基本概念

    应用程序必须经过编译、汇编和链接后才变成可执行文件,在链接时,要对所有目标文件进行地址重定位,建立符号引用规则,同时为变量、函数等分配运行地址。当程序执行时,系统必须把代码加载到链接时所指定的地址空间即链接地址(链接地址介绍在链接地址与运行地址,以保证程序在执行过程中对变量、函数等符号的正确引用,使程序正常运行。
    通常情况下,将bootloader程序下载到ROM0x0地址进行启动(比如固化到NorFlash中,再把链接起始地址指定为0,这样PC运行地址与链接地址就一样,代码能正常运行)。然而在很多的设计中,比如将bootloader固化在NAND中,在系统NAND启动复位后S3C2440ANAND控制器自动读取NAND中存储的前4K的代码到s3c2440A中称之为steppingstone4K片内RAM中,steppingstone中的代码用来进行一些非核心的硬件初始化,并把剩下的bootloader拷贝到SDRAM中运行,这样代码就既要能在片内RAM的0地址执行,也要能在SDRAM的地址上执行,这就需要位置无关代码来完成了。
    位置无关代码指代码不在链接时指定的运行地址空间也可以执行,即一段加载到任意地址空间都能执行的特殊代码。通常在像文件的前4K代码要用位置无关码设计。 
    位置无关代码可以用于以下场合:
      1. 程序在运行期间动态加载到内存; 
      2. 程序在不同场合与不同程序组合后加载到内存(共享的动态链接库);  
      3. 在运行期间不同地址相互之间的映射(如bootloader)。
   
    总结:位置无关代码,即该段代码无论放在内存的哪个地址,都能正确运行。究其原因,是因为代码里没有使用绝对地址,都是相对地址。而位置相关码,即它的地址与代码处于的位置相关,是绝对地址,如:mov PC ,#0xff;ldr  pc,=0xffff等。如果你的这段代码需要实现位置无关,那么你就不能使用绝对寻址指令,否则的话就是位置有关。

2. 位置无关码的写法

2.1 BL

    BL:带链接分支跳转指令,也是位置无关码(相对位置),用于调用函数用的

2.2 B

    B:分支跳转指令,指目标不能太远,一般用于同一个文件下的目标地址跳转

2.3 LDR

    LDR:通常都是作加载指令的,但是它也可以作伪指令,通常有两种不同的表示:

2.3.1 加载指令: (不加=号,位置无关)

LDR R0,Label 

    表示把Label表示的地址上的值存到R0(Label为程序标号,Label必须是当前指令的-4~4KB范围内),CPU通过计算偏移值得到,也就是相对地址,是位置无关码。

2.3.2 伪指令: (加=号,位置相关)

LDR r0, =Label

   如果Label是标号,表示把Label的地址存到R0中,这里面出现的“=”预示着这是一条伪指令,这个是取得标号Label绝对地址”,这个绝对地址就是在link的时候确定的,也就是链接地址或叫做编译地址
    如果Label是立即数,表示把立即数存入R0中。

bl  main /* 位置无关 */
ldr pc, =main /* 把main的地址放在pc,位置相关 */

    显然,用LDR时,加不加=号有很大区别:
      无=号表示取该标号处的值,位置无关;
      有=号表示取该标号的地址,位置相关。

2.4  bl/b调用的c语言函数里面也不要使用全局变量,因为c里面的全局变量的地址是根据链接地址生成的

3. 位置相关码示例

    汇编文件部分代码如下:

Reset:                  
    ldr sp, =4096           @ 设置栈指针,以下都是C函数,调用前需要设好栈
    bl  disable_watch_dog   @ 关闭WATCHDOG,否则CPU会不断重启
    // bl是位置无关码,相当于:PCnew = PC + 偏移
    //                         PCnew = (4+8) + 0x28 = 0x34
    
    //ldr pc, =disable_watch_dog  /* 这样写将出错 */
    
    bl  clock_init          @ 设置MPLL,改变FCLK、HCLK、PCLK
    bl  memsetup            @ 设置存储控制器以使用SDRAM
    bl  copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
    ldr pc, =on_sdram                   @ 跳到SDRAM中继续执行
on_sdram:
    ldr sp, =0x34000000     @ 设置栈指针
    ldr lr, =halt_loop      @ 设置返回地址
    ldr pc, =main           @ 调用main函数
halt_loop:
    b   halt_loop

    链接脚本如下,链接地址在0X30000000:

SECTIONS {
    . = 0x30000000;
    .text          :   { *(.text) }
    .rodata ALIGN(4) : {*(.rodata)} 
    .data ALIGN(4) : { *(.data) }
    .bss ALIGN(4)  : { *(.bss)  *(COMMON) }
}

    反汇编如下:

30000000 <_start>:
30000000:    e3a0da01     mov    sp, #4096    ; 0x1000
30000004:    eb00000a     bl    30000034 <disable_watch_dog>
30000008:    eb00000d     bl    30000044 <clock_init>
3000000c:    eb000026     bl    300000ac <memsetup>
30000010:    eb000040     bl    30000118 <copy_steppingstone_to_sdram>
30000014:    e59ff00c     ldr    pc, [pc, #12]    ; 30000028 <.text+0x28>

30000018 <on_sdram>:
30000018:    e3a0d30d     mov    sp, #872415232    ; 0x34000000
3000001c:    e59fe008     ldr    lr, [pc, #8]    ; 3000002c <.text+0x2c>
30000020:    e59ff008     ldr    pc, [pc, #8]    ; 30000030 <.text+0x30>

30000024 <halt_loop>:
30000024:    eafffffe     b    30000024 <halt_loop>
30000028:    30000018     andcc    r0, r0, r8, lsl r0
3000002c:    30000024     andcc    r0, r0, r4, lsr #32
30000030:    30000200     andcc    r0, r0, r0, lsl #4

30000034 <disable_watch_dog>:
   ...  ...

    在汇编文件中有如下代码:   
      ldr pc, =on_sdram
    这一句等于反汇编中如下代码:
      30000014:    e59ff00c     ldr    pc, [pc, #12]    ; 30000028 <.text+0x28>
    其中30000014表示链接地址,e59ff00c表示指令机器码。下面进行分析,首先ARM中有两级流水线,如下图所示:
   

    PC指向正被取指的指令,而非正在执行的指令(也就是说PC的地址值是正在执行代码的地址值加上8)。故PC的地址值应该是此时的指令地址值0x30000014+8,而[pc, #12]表示0x30000014+8+12=0x30000028(8+12=20(十进制)=0x14(十六进制))。查看反汇编中的指令地址为0x30000028所对应的指令机器码如下:
      30000028:    30000018     andcc    r0, r0, r8, lsl r0
,可以看到0x30000028所对应指令机器码是30000018。当执行ldr    pc, [pc, #12]就令pc=0x30000018了。当0x30000018地址上没有对应的代码,而PC执行到该地址时,就会出错,这就是位置相关码(执行位置相关码时链接地址与运行地址必须一样)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

位置无关码介绍 的相关文章

  • mac 如何安装hp laserjet m1136驱动

    直接在苹果的官网下载驱动就可以了 要下V5 1的那个版本https support apple com kb DL1888 viewlocale zh CN locale zh CN 选择系统偏好设置中的打印机 然后选择相对应的版本就可以了
  • C++语言基础

    1 1 1 简述下C 语言的特点 参考回答 C 在C语言基础上引入了面对对象的机制 同时也兼容C语言 C 有三大特性 1 封装 2 继承 3 多态 C 语言编写出的程序结构清晰 易于扩充 程序可读性好 C 生成的代码质量高 运行效率高 仅比
  • win10连接文件服务器记住密码如何删除,win10系统删除已记住的访问共享的账户与密码的操作方法...

    win10系统删除已记住的访问共享的账户与密码的操作方法 很多win10用户在使用电脑的时候 会发现win10系统删除已记住的访问共享的账户与密码的的现象 根据小编的调查并不是所有的朋友都知道win10系统删除已记住的访问共享的账户与密码的
  • Inno Setup 系列之先卸载之后再安装

    Inno Setup 系列之先卸载之后再安装 需求使用Inno Setup打包程序之后 很多时候我们需要在安装文件之前卸载原有的程序而不是覆盖安装 本文的Code就是实现了这样的功能 如果想要在安装前先卸载 那么需要加下面代码 需要注意的是
  • 案例分析2

    文章目录 16 质量属性 数据库 嵌入式 web 软件设计 15 质量属性 飞机起飞 嵌入式 数据库 数据持久层 14 mvc 数据流图 构件 质量属性 web 13 ESB mvc 安全 12 架构风格 ODP 嵌入式 设计模式 关系型数
  • QT-智能指针

    lt 智能指针与普通指针 最明显区别普通指针 要手动去释放 智能指针出了作用域自动释放 完全不用担心有内存忘记释放的操作 gt 智能指针 1 QScopedPointer 区域指针 2 QSharedPointer 智能指针 强引用计数指针
  • python 正则模块(re)

    1 正则表达式常见的具体应用场景如下 手机号校验 邮箱校验 身份证校验 网页标签匹配 车牌号校验 中文校验 2 re模块 正则表达式是一个特殊的字符序列 它能帮助你方便的检查一个字符串是否与某种模式匹配 Python 自1 5版本起增加了r
  • 加载人物模型

    var abPath prefab character nanjianshi 01all unity3d var assetName Nanjianshi 01All LuaHelper GetResManager LoadPrefabAs
  • LDAP和netty面试题

  • 自动化接口测试实战-第04天-读取外部数据文件、iHRM项目实战

    更多功能测试以及全套学习路线图均在专栏 戳进去领取 系列文章目录 身为开发必知必会的Linux Linux远程连接 命令的使用 Linux命令大全 唯一以案例详解文 持续更新中 Linux命令大全以及数据库 唯一以案例详解文 已完结 Web
  • 一次CNVD-2020-10487漏洞利用

    0x00漏洞简介 CNVD 2020 10487 tomcat ajp文件读取漏洞 0x01开始 某次对一个目标进行测试 用routerscan扫描搜集的C段资产 发现某个IP开放了22 6379 8009等端口 看到8009就想到了tom
  • 服务器ssd硬盘接笔记本,M.2固态硬盘怎么安装 台式机与笔记本电脑安装M.2 SSD方法图解...

    固态硬盘接口众多 不过目前最流行的还是SATA3 0和M 2接口SSD 不过 伴随着SATA3 0接口存在性能瓶颈 越来越多高速固态硬盘采用了M 2接口 那么M 2固态硬盘怎么安装 下面脚本之家就来教大家如何给台式电脑或者笔记本安装M 2固
  • 2.5.5 创建、安装VIO分区

    最后更新2021 07 26 与创建AIX分区相同 但在HMC选择创建vio server 分区 图 261 创建VIO分区 输入分区名 VIO分区的Partition ID与名称都可以随意指定 但为了便于管理 建议分区的名称就是用DNS可
  • 静态分析的四种基本方法

    数据流分析 Data Flow Analysis 将数据看作是图 节点是程序的基本快 边是描述控制如何从一个基本快转移掉另一个基本快 图可以解决很多问题 例如 以 图中边的抽象得出数学方程 七届就是可达性问题的答案 PREfix SLAM静
  • 服务器怎么清空系统盘,服务器怎么清空数据

    服务器怎么清空数据 内容精选 换一换 华为云帮助中心 为用户提供产品简介 价格说明 购买指南 用户指南 API参考 最佳实践 常见问题 视频帮助等技术文档 帮助您快速上手使用华为云服务 无法看到 Windows 实例数据盘怎么办 磁盘挂载至
  • IPFS方得社区周欢:web3.0时代的分布式存储畅想

    链茶访是链茶馆新开辟的区块链项目报道专栏 每周会对一个项目团队进行专访 链茶馆将挖掘不同项目的闪光点 讲述区块链开发者的创业故事 为各位区块链同侪提供最新的项目资讯与行业动向 链茶馆今天采访了IPFS方得社区创始人周欢 该社区目前有4万用户
  • unity 常用的设计模式

    一 单例模式 在我们的整个游戏生命周期当中 有很多对象从始至终有且只有一个 这个唯一的实例只需要生成一次 并且直到游戏结束才需要销毁 单例模式一般应用于管理器类 或者是一些需要持久化存在的对象 优点 写起来很方便 调用方便 缺点 容易形成依
  • 深度学习3D可视化工具——Zetane Engine

    神经网络在工作的时候 里面到底是什么样 为了能透视这个 AI黑箱 中的过程 加拿大蒙特利尔一家公司开发一个3D可视化工具Zetane Engine 只需要上传一个模型 Zetane Engine就可以巡视整个神经网络 并且还可以放大网络中的
  • React-Router实战:路由传参(正则表达式)

    首先我们先做个路由普通传参的例子 一 准备工作 1 目录结构 index js components App gt App js Home gt Home js About gt About js News gt News js 2 源码

随机推荐

  • Qt常用命令和pro参数

    Qt常用工具 命令行指令 位于 C Qt5 7 1 5 7 msvc2015 64 bin 命令 功能 assistant 帮助文档 designer 设计器 linguist 翻译工具 lupdate 提取翻译字符串和生成ts文件 lre
  • logback不输出至文件_Logback日志使用详解

    Logback是由log4j创始人设计的一个开源日志组件 概述 Logback建立于三个主要类之上 日志记录器 Logger 输出端 Appender 和日志格式化器 Layout 这三种组件协同工作 使开发者可以按照消息类型和级别来记录消
  • caffe 红绿灯识别

    coding utf 8 加载必要的库 import numpy as np import sys os 设置当前目录 caffe root home ubuntu caffe sys path insert 0 caffe root py
  • Report, 20150402, Formulas on Entropy, Part I

    Section 1 Papoulis s Formula Lemma 1 If the random variables y 1 ldots y n are the linear combination of random variable
  • Artifactory Maven 使用教程

    Maven 仓库使用 修改 Maven 配置文件 选择左侧 Artifacts 选择自己需要上传的 Maven 仓库 点击Set Me Up 在弹出的设置框中点击 点击下载生成的文件 将生成的文件放到此目录下 或者你自己的 Maven 目录
  • 线性回归模型

    线性回归是最简单的机器学习模型 也是最基础最重要的分析工具 易于实现 本文将将简单讲述线性回归 最小二乘法和梯度下降三种算法 目录 1 线性回归方程 OLS 2 最小二乘法 OLS 3 梯度下降 GD 3 1超参数 的选择 3 2局部最小值
  • Android使用OpenCV来实现bitmap独立设置每个圆角

    Android使用OpenCV来实现bitmap独立设置每个圆角 关于opencv集成请参考我的其他文章 这里方便起见已经封装成java方法供大家调用 代码如下 public static Bitmap drawCircleRadius i
  • 打乱1-100的个数字的顺序

    package test import java util Random public class Test2 public static void swap int a int i int j if a null a length 0 i
  • Weex页面的编写——Weex的学习之路(六)

    通过前几博客我们把weex的内置组件都学习完了 组件的单独使用想必都可以了 那么 这次我们来做weex实际页面的编写 见证一下 一套代码在Android Ios和H5上使用 在weex官网推荐我们使用Weex Studio作为编译器 其实这
  • Unity 3D作业二:离散仿真引擎基础

    前言 中山大学中山大学数据科学与计算机学院3D游戏课程学习记录博客 简答题 1 解释游戏对象 GameObjects 和资源 Assets 的区别与联系 游戏对象 出现在游戏场景中 充当游戏的组件 游戏对象不做任何事情 需要特殊属性才能成为
  • Xcode Executable Not Found

    问题 Xcode编译项目报Executable Not Found的错误 Details Details Executable Not Found Domain DVTMachOErrorDomain Code 5 Recovery Sug
  • Rust 删除排序数组中的重复项

    力扣https leetcode cn com problems remove duplicates from sorted array 参考代码和注释 fn main let mut v Vec
  • Linux下Elasticsearch离线安装

    先去下载离线安装包 我这里是7 10 0 Past Releases of Elastic Stack Software Elastic 上传到 usr local下 解压 tar zxvf elasticsearch 7 10 0 lin
  • 【MATLAB】MATLAB打开后,提示内部崩溃,直接闪退关闭——解决方法

    问题描述 在第一次安装MATLAB软件时 正常使用 过了一段时间后 突然发现在命令行可以正常使用 但运行编译文件里的程序便会报 MathWorks 崩溃的错误 提示MATLAB遇到了内部问题 需要关闭 结果MATLAB自己闪退结束 解决方法
  • MATLAB(6)GUI应用介绍

    目录 GUI编辑器 控件 属性 回调函数 MATLAB常见的控件 普通按钮 切换按钮 可编辑文本 字符获取 字符显示 复选框 单选按钮 弹出式菜单 滑动条 列表框 表 坐标区 附录 各文件共享数据 保存 获取 GUI编辑器 MATLAB的G
  • 【问题记录】05 Host key for [ip] has changed and you have requested strict checking.Host key verification

    1 报错信息如下 为主机ip WARNING REMOTE HOST IDENTIFICATION HAS CHANGED IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY Someo
  • 操作系统实验——互斥与同步

    目录 1 SYSTEM V信号量 1 创建或打开 semget 2 申请或释放 semop 3 设置信号量 semctl 2 POSIX信号量 1 初始化 sem init 2 申请和释放 sem wait 3 销毁 sem destroy
  • 详细记录YOLACT实例分割ncnn实现

    点击上方 AI算法修炼营 选择加星标或 置顶 标题以下 全是干货 整理 公众号 深度学习与计算机视觉 作者 nihui 链接 https zhuanlan zhihu com p 128974102 本文转载自知乎 作者已授权 未经许可请勿
  • 《写给大家看的设计书(第4版)》读书笔记

    文章目录 前言 设计原则 亲密性 对齐 重复 对比 结语 前言 设计类的书籍看过一些 大多分为两类 一类是讲基础的 构图 明暗 色彩等基础理论 还有一类是分享介绍具体案里的 这两类书籍对于大多数并不想真正成为设计师的人来说很多时候并没有什么
  • 位置无关码介绍

    1 基本概念 应用程序必须经过编译 汇编和链接后才变成可执行文件 在链接时 要对所有目标文件进行地址重定位 建立符号引用规则 同时为变量 函数等分配运行地址 当程序执行时 系统必须把代码加载到链接时所指定的地址空间即链接地址 链接地址介绍在