这篇文章是自己疑惑究竟地址无关性是如何实现,然后查看汇编和CPU指令手册,最后分析解除自己疑惑的,高手不要鄙视,哈哈。

编译C代码时候需要制定--acps/ropi选项,如下例子:

 void SystemInit(void)
{
}
void fun_for_sub(void)
{
int j;
for(j=;j >=; j--)
;
}
int main(void)
{
fun_for_sub();
while();
}

C-example

编译:

armcc  -c --cpu Cortex-M3 -O0 --apcs=interwork --apcs /ropi/rwpi -o main.o main.c

使用fromelf查看汇编代码

fromelf.exe -s -c main.o

text段生成的汇编代码如下:

 ** Section #1 '.text' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
Size : 14 bytes (alignment 2)
Address: 0x00000000 $t
.text
SystemInit
0x00000000: 4770 pG BX lr
fun_for_sub
0x00000002: 4770 pG BX lr
main
0x00000004: b500 .. PUSH {lr}
0x00000006: f7fffffe .... BL fun_for_sub ; 0x2 Section #
0x0000000a: 205a Z MOVS r0,#0x5a
0x0000000c: bd00 .. POP {pc}

汇编指令

查看关键的一句调用函数fun_for_sub的汇编代码:

0x00000006:    f7fffffe       ....    BL       fun_for_sub ; 0x2 Section #

查找arm的官方DDI0403D_arm_architecture_v7m_reference_manual_errata_markup_1_0.pdf关于BL指令的解释如下:

Branch with Link (immediate) calls a subroutine at a PC-relative address.

得知BL是一条PC相关的指令。

具体看BL指令的构成:

根据我们产生的指令f7fffffe,

对应如下:

f7ff  :  15  14  13  12  11  10  9  8  7  6  5  4  3  2  1

        1   1   1   1   0   1  1  1  1  1  1  1  1  1  1
fffe  :  15  14  13  12  11  10  9  8  7  6  5  4  3  2  1

        1   1   1   1   1   1  1  1  1  1  1  1  1  1  0
符号位S=1,J1=1,J2=1,imm10 = 11 1111 1111,imm11 = 111 1111 1110

所以I1 = !(J1~S) = 1,  I2 = !(J2~S) = 1,

imm32 = SignExtend(S:I1:I2:imm10:imm11:’0’,32) = SignExtend(1:1:1:11 1111 1111:111 1111 1110:’0’,32) = 1111 1111 1111 1111 1111 1111 1111 1100 = 0xfffffffc。

0xfffffffc是-4的补码,另外当前PC是0x00000006,

再根据上面的Operation最后一步BranchWritePC( PC + imm32)

最终跳转到0x6 + (-4) = 0x2的地址出,即函数fun_for_sub的地址,因此实现根据当前PC实现了地址无关性的代码。

在X86平台下面也是差不多的原理,使用的也是基于PC相关的跳转指令。《程序员的自我修养—链接、装载和库》讲得很好。

Cortex-M3 动态加载一(地址无关代码实现)的更多相关文章

  1. 动态加载js、css 代码

    一.原生js: /** * 加载js和css文件 * @param jsonData.path 前缀路径 * @param jsonData.url 需要加载的js路径或css路径 * @param ...

  2. Android动态加载框架汇总

    几种动态加载的比较 1.Tinker 用途:热修复 GitHub地址:https://github.com/Tencent/tinker/ 使用:http://www.jianshu.com/p/f6 ...

  3. 关于实现Extjs动态加载类的方式实现

    Extjs4以前的版本没有动态加载类的方式,这样开发程序的时候加载很多的js会导致加载变慢,由于本人一直使用extjs3的版本进行开发,于是简单实现了一个动态加载类的管理器,使用方式与extjs4的方 ...

  4. java动态加载配置文件(申明:来源于网络)

    java动态加载配置文件 地址:http://blog.csdn.net/longvs/article/details/9361449

  5. [Android]动态加载/热部署框架汇总

    1.DroidPlugin 用途:动态加载 使用案例:360手机助手 GitHub地址:https://github.com/Qihoo360/DroidPlugin ppt介绍:https://gi ...

  6. flash的动态加载技术

    这里所说的动态加载技术, 主要是指代码模块(可以是swc也可以是swf)的动态加载.即主swf在运行的时候, 可以根据需要动态加载所需的代码模块. 为了讨论方便, 下面所说的代码模块都用swc表示,用 ...

  7. ios ableviewcell的动态加载数据,模仿喜马拉雅动态数据加载

    iphone(UITableViewCell)动态加载图片http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Intr ...

  8. Delphi静态加载DLL和动态加载DLL示例

    下面以Delphi调用触摸屏动态库xtkutility.dll为例子,说明如何静态加载DLL和动态加载DLL. 直接上代码. 1.静态加载示例 unit Unit1; interface uses W ...

  9. vue路由动态加载

    注意:是动态加载不是动态路由 解决的问题: 动态配置菜单栏的路由参数--实现菜单级的权限控制 问题成因: 在vue实例化的时候vuex.vue-router 就需要加载完毕,无法使用异步的方式从服务器 ...

  10. JavaScript动态加载js文件

    /********************************************************************* * JavaScript动态加载js文件 * 说明: * ...

随机推荐

  1. BZOJ 4011: [HNOI2015]落忆枫音( dp )

    DAG上有个环, 先按DAG计数(所有节点入度的乘积), 然后再减去按拓扑序dp求出的不合法方案数(形成环的方案数). ---------------------------------------- ...

  2. c#访问各数据库的providerName各驱动

    在machine.config(C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/CONFIG)文件中有这么一段: <system.data> & ...

  3. ContentProvider类的解析

    一.ContentProvider类 1.作用:专门用于不同应用之间进行数据共享的方式. 二.实现方法 1.创建ContenteProvider类 步骤一:继承ContentProvider接口,重写 ...

  4. 《UNIX网络编程》TCP客户端服务器例子

    最近在看<UNIX网络编程>(简称unp)和<Linux程序设计>,对于unp中第一个获取服务器时间的例子,实践起来总是有点头痛的,因为作者将声明全部包含在了unp.h里,导致 ...

  5. Linux07--Shell程序设计03 通配符与正则表达式

    通配符 通配符可用于代替字符. 通常地,星号“*”匹配0个或以上的字符,问号“?”匹配1个字符. 使用情况: 1.文件和目录 在CP/M.DOS.Microsoft Windows和类Unix操作系统 ...

  6. 用实例给新手讲解RSA加密算法

    图为 RSA公开密钥算法的发明人,从左到右Ron Rivest, Adi Shamir, Leonard Adleman. 照片摄于1978年 RSA加密算法是最常用的非对称加密算法,CFCA在证书服 ...

  7. 对TCP说三道四(三次握手)

    夜朦胧,人方静,无聊的人打开了无聊的电脑看到了一张无聊的图,想着想着就睡着了,梦到了人a和人b的一次聊天. 有一天,a有事情想跟b商量就问b“有时间么,想和你聊一下天”,b想了一会发现自己能抽出时间就 ...

  8. C++关键字之static

    一.面向过程设计中的static 1.静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量.我们先举一个静态全局变量的例子,如下: [cpp]   #include& ...

  9. OC中ARC forbids explicit message send of release错误(转)

    ARC forbids explicit message send of'release' 很显然,是ARC的问题. 错误原因:在创建工程的时候点选了“Use Automatic Reference ...

  10. Neutron数据库同步错误 NotImplementedError: No support for ALTER of constraints in SQLite dialect

    错误信息 root@controller:~# su -s /bin/sh -c "neutron-db-manage --config-file /etc/neutron/neutron. ...