位置无关码 位置相关码

在汇编中  使用位置无关码

b,bl

在c语言中 使用位置无关码

不用全局变量  不用静态变量

位置无关码:CPU取指时,总是相对于本条执行指令的相对地址去取指。比如指行一个ADD指令时,PC要取下一指令的地址,就在原来的基础上+4。这就不管你代码放在存储器的任何位置,只要他们的相对地址没有改变,就能正常执行程序。一般上电复位那几条语句就必须是位置无关码指令。

位置相关码:可以这样来说,就是CPU每次取指都从绝对位置去取,而不是上面的相对位置。这个绝对地址就是相对起始地址0来说的。这样,就要求你在存放程序时,必须给连接脚本所规定的一样,把代码放到指定位置
1.A排在第一的位置,B排在第二的位置2.A排在B的前面这两种情况,都说明的A和B的位置关系,而第一种跟位置相关,属于绝对地址;而第二种情况则跟位置无关,属于相对地址。

位置无关与位置相关代码是关于arm程序在跳转时的寻址方式的两种,一般情况下两种方法都能达到跳转到目的地址的目标,但是在某些特定的环境下,两种跳转方法得到的结果相关较大。

位置无关代码的跳转可通过“B或BL 标号”命令执行,当执行B或BL命令实现跳转时,实际的二进制代码在跳转时是执行:计算可执行代码中目标地址到当前PC值处的距离,然后把该距离值加上当前的PC值,然后赋值给PC寄存器实现跳转,该跳转方法由于指令的地址域只有26位,所以它只能向前/向后寻址32M位地址,如果目标地址到当前PC值的距离大于该值时,可使用伪指令“ADR和ADRL PC,=标号地址”实现跳转,实际执行过程是先计算目标址址到当前PC的距离,然后把当前PC值加上距离值赋值到目标寄存器PC中,实现跳转,ADR与B或BL功能类似,但ADRL可以实现全部范围内的跳转,其通过把目标地址与当前PC的距离值存储到一个缓存字中,然后把缓存字中的值加载到寄存器PC中。

位置相关跳转也可以叫绝对位置跳转,一般使用伪指令LDR PC,=label实现跳转到label标号的链接地址中,绝对地址也就是链接地址。这里位置相关及位置无关本质上的区别其实是链接地址与运行地址的区别。

在无操作系统中的裸机代码中,如果链接的偏移基址为0,则绝对位置跳转与相对位置跳转的效果是一样的,而对于一些把可执行代码拷贝到ram中再运行的程序中,链接地址与起始运行地址是不相同的,一般地链接地址是一个ram逻辑地址内的一个数值,而运行地址则是代码烧写的flash等存储器件的逻辑地址,一般是0地址。链接的偏移地址可以通过在编译时通过在链接脚本或Makefile中指定。

在完成可执行代码从flash到ram的拷贝后,通过LDR PC,=label指令跳转到内存中执行程序,而在这之前执行的代码跳转必须是位置无关的,否则会出现跑飞的异常。

B label BL label //位置无关跳转到label

ADR R0,label ADRL R0,=label //获取label到当前程序的偏移距离

ADR PC,label ADRL PC,=label //位置无关跳转到label

LDR PC,=label //位置相关的绝对位置跳转

LDR R0,=label //获取label到当前程序的偏移距离,注意这里不是获取label的(链接地址)绝对地址

LDR R0,=0x500000C0

LDR R1,[R0]

LDR R2,=0x00

STR R2,[R0]

LDR R0,=label加载label数据到寄存器R0中,如果label大于255则把LDR翻译成上述位置无关的伪指令,如果小于255则直接是用LDR指令进行立即数寻址方式

参考:

http://blog.chinaunix.net/uid-10696433-id-2935776.html

http://m.blog.csdn.net/blog/zhaigch/39433601

时间: 2024-10-13 16:27:28

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

计算机科学基础知识(四)动态库和位置无关代码

一.前言 本文主要描述了动态库以及和动态库有紧密联系的位置无关代码的相关资讯.首先介绍了动态库和位置无关代码的源由,了解这些背景知识有助于理解和学习动态库.随后,我们通过加-fPIC和不加这个编译选项分别编译出两个relocatable object file,看看编译器是如何生成位置无关代码的.最后,我们自己动手编写一个简单的动态库,并解析了一些symbol Visibility.动态符号表等一些相关基本概念. 本文中的描述是基于ARM MCU,GNU/linux平台而言的,本文是个人对动态库

位置无关码

ARM下的位置无关和相关码 为什么需要位置无关码? 见 : U-BOOT详解(什么是<编译地址>?什么是<运行地址>?)  http://bbs.21ic.com/forum.php?mod=viewthread&tid=857037&typeid=114       ARM位置无关代码设计规范  http://wenku.baidu.com/view/5ef25b890b4c2e3f562763a8.html 位置无关可执行文件PIE包括位置无关代码PIC和位置无

位置无关码(BL)与绝对位置码(LDR)

BL :带连接分支跳转指令,也是位置无关码(相对位置),一般用于带返回的子程序跳转,B指令是用于无返回的跳转. LDR:通常都是作加载指令的,但是它也可以作伪指令,通常有两种不同的表示:  1)LDR pc, =MyHandleIRQ 表示将MyHandleIRQ地址放入pc寄存器中,相当于PC=MyHandleIRQ . 2)LDR PC,MyHandleIRQ 表示将 MyHandleIRQ地址中的值放入pc寄存器中,类似于C语言中的指针形式,相当于PC=*(MyHandleIRQ ). 实

代码重定位和位置无关码

通过前面的学习,我们知道,把可执行程序从一个位置复制到另一个位置的过程叫做重定位. 现在有两种方式,第一种是只重定位data段到内存(sdram),为什么需要重定位?因为有些flash的写操作,不是简单地内存访问,通常我们使用sdram这个介质作为程序运行的载体.但是只重定位data段这种方式存在弊端.第一,我们的调试工具通常不支持这种分体形式(比如我们的之前的代码在0地址开始存放text和rodata段,而在间隔很远处sdram 0x30000000存放data段,这就是分体的形式)的代码:第

韦东山yy公开课笔记(2)--汇编,段,栈,重定位/链接地址,位置无关吗

1. 要不要学习汇编 可以只懂一点,工作中基本不用,一旦用就是出了大问题 ldr : load 读内存 ldr r0, [r1]  : r1里存放的是地址值, 去这个地址读取4字节的内容,存入r0 str : stroe 写内存 str r0, [r1]  : r1里存放的是地址值, 把r0里的4字节数据存入这个地址 所有的汇编.C程序也好,终极目标就是:读写某个地址 2. 程序为何要分为代码段.数据段.BSS段 程序的指令等是只读的,可以把它们归为一类,以便运行时可以放在ROM等设备上, 当然

uboot之位置无关代码解析

在之前的话 新年过去了,那么久没有好好学习,感觉好颓废,现在就uboot的一些基础问题做一些笔记,顺便分享给大家,不过由于见识有限,如果有不足之处请多多指教. 位置无关?什么意思?我们先了解一些基础知识..... 我们都知道我们写的代码最后是运行在内存(SDRAM或者SRAM,通常是SDRAM)中的,但是在运行之前他们是保存在诸如nand.flash等非易失存储设备中的,而这些存储设备的地址要映射到CPU能够寻找的地址上(一般映射在0X0地址上,这个后面详细解释),这样才能得到要运行的代码.而代

微信支付宝扫码支付相关接口

微信支付宝扫码支付相关接口 ##################支付宝扫码支付################## 当面付--扫码支付:商户专柜或者收银台打印或者副屏展示支付宝二维码,用户使用支付宝钱包扫码工具扫描二维码,并在手机端完成付款. 文档中心:http://doc.open.alipay.com/doc2/detail?spm=0.0.0.0.E3tvGh&treeId=26&articleId=103286&docType=1SDK下载地址:http://doc.ope

对位置无关代码的理解

今天在看uboot编译流程的时候,突然发现对程序的地址相关性的记忆又有点模糊了.搞嵌入式软件就是这个不好,需要学习和掌握很多知识点,才能够对开发中的所有细节都有全面的掌握.可是往往这种掌握又不是很有必要的,因为很多细节性的问题在实际开发过程中,又不一定需要去关注,或者说关注的很少.这就直接导致了学习和掌握了很多细节的知识,往往久了不用,就淡忘了. 比如这里提到的代码地址相关性,以前在搞VxWorks,尤其是bootrom存放位置的时候就有过分析.bootrom编译的时候是不用考虑代码运行位置的,

共享库中的位置无关代码(PIC)

原作者:Eli Bendersky http://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries/ 在之前的文章里我已经描述过在将共享库载入程序地址空间时需要特殊的处理.简而言之,在链接器创建共享库时,它不能预先知道这个库将在哪里载入.这给在库里访问数据与代码带来了麻烦,应该使得这些访问指向正确的内存位置. 在Linux ELF共享库里解决这个问题有两个主要途径: 1.