Cortex-M3 动态加载一(地址无关代码实现)

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

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

 1 void SystemInit(void)
 2 {
 3 }
 4 void fun_for_sub(void)
 5 {
 6     int j;
 7     for(j=65535;j >=0; j--)
 8       ;
 9 }
10 int main(void)
11 {
12          fun_for_sub();
13          while(1);
14 }
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段生成的汇编代码如下:

 1 ** Section #1 '.text' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
 2     Size   : 14 bytes (alignment 2)
 3     Address: 0x00000000
 4 
 5     $t
 6     .text
 7     SystemInit
 8         0x00000000:    4770        pG      BX       lr
 9     fun_for_sub
10         0x00000002:    4770        pG      BX       lr
11     main
12         0x00000004:    b500        ..      PUSH     {lr}
13         0x00000006:    f7fffffe       ....    BL       fun_for_sub ; 0x2 Section #1
14         0x0000000a:    205a        Z       MOVS     r0,#0x5a
15         0x0000000c:    bd00        ..      POP      {pc}
汇编指令

 

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

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

 

查找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相关的跳转指令。《程序员的自我修养—链接、装载和库》讲得很好。

转载于:https://www.cnblogs.com/ppym/p/3655425.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值