程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Cortex-M3 動態加載一(地址無關代碼實現)

Cortex-M3 動態加載一(地址無關代碼實現)

編輯:關於C語言

這篇文章是自己疑惑究竟地址無關性是如何實現,然後查看匯編和CPU指令手冊,最後分析解除自己疑惑的,高手不要鄙視,哈哈。

編譯C代碼時候需要制定--acps/ropi選項,如下例子:

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段生成的匯編代碼如下:

匯編指令

 

查看關鍵的一句調用函數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相關的跳轉指令。《程序員的自我修養—鏈接、裝載和庫》講得很好。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved