最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

13.5代碼重定位_代碼重定位與位置無關(guān)碼

2020-08-21 14:48 作者:韋東山  | 我要投稿

????????一個程序,由代碼段、只讀數(shù)據(jù)段、數(shù)據(jù)段、bss段等組成。 程序一開始可以燒在Nor Flash上面,運行時代碼段仍可以在Nor Flash運行,但對于數(shù)據(jù)段,就必須把數(shù)據(jù)段移到SDRAM中,因為只要在SDRAM里面,數(shù)據(jù)段的變量才能被寫操作,把程序從一個位置移動到另一個位置,把這個過程就稱為重定位。 前面的例子,我們只是重定位了數(shù)據(jù)段,這里我們再嘗試重定位整個代碼。


先梳理下把整個程序復(fù)制到SDRAM需要哪些技術(shù)細節(jié):
1. 把程序從Flash復(fù)制到運行地址,鏈接腳本中就要指定運行地址為SDRAM地址;
2. 編譯鏈接生成的bin文件,需要在SDRAM地址上運行,但上電后卻必須先在0地址運行,這就要求重定位之前的代碼與位置無關(guān)(是位置無關(guān)碼);

參考Uboot修改鏈接腳本:?

????????現(xiàn)在我們寫的這個鏈接腳本,稱為一體式鏈接腳本,對比前面的分體式鏈接腳本區(qū)別在于代碼段和數(shù)據(jù)段的存放位置是否是分開的。

例如現(xiàn)在的一體式鏈接腳本的代碼段后面依次就是只讀數(shù)據(jù)段、數(shù)據(jù)段、bss段,都是連續(xù)在一起的。 分體式鏈接腳本則是代碼段、只讀數(shù)據(jù)段,中間相關(guān)很遠之后才是數(shù)據(jù)段、bss段。


我們以后的代碼更多的采用一體式鏈接腳本,原因如下:
1. 分體式鏈接腳本適合單片機,單片機自帶有flash,不需要再將代碼復(fù)制到內(nèi)存占用空間。而我們的嵌入式系統(tǒng)內(nèi)存非常大,沒必要節(jié)省這點空間,并且有些嵌入式系統(tǒng)沒有Nor Flash等可以直接運行代碼的Flash,就需要從Nand Flash或者SD卡復(fù)制整個代碼到內(nèi)存;
2. JTAG等調(diào)試器一般只支持一體式鏈接腳本;?


修改start.S段?

將修改后的代碼重新編譯燒寫在Nor Flash上,上電運行。 對本代碼的啟動情況進行分析:

Chapter13 lesson5 001.jpg

在生成的bin文件里,代碼保存的位置是0x30000000。隨后燒寫到NOR Flash的0地址,但代碼的結(jié)構(gòu)沒有變化。之后再重定位到SDRAM。


查看反匯編:?

可以看到現(xiàn)在變成了bl 30000478,但兩個的機器碼eb000106都是一樣的,機器碼一樣,執(zhí)行的內(nèi)容肯定都是一樣的。 因此這里并不是跳轉(zhuǎn)到顯示的地址,而是跳轉(zhuǎn)到: pc + offset,這個由鏈接器決定。


假設(shè)程序從0x30000000執(zhí)行,當(dāng)前指令地址:0x3000005c ,那么就是跳到0x30000478;如果程序從0運行,當(dāng)前指令地址:0x5c 調(diào)到:0x00000478

跳轉(zhuǎn)到某個地址并不是由bl指令所決定,而是由當(dāng)前pc值決定。反匯編顯示這個值只是為了方便讀代碼。

重點: 反匯編文件里, B或BL 某個值,只是起到方便查看的作用,并不是真的跳轉(zhuǎn)。?


怎么寫位置無關(guān)碼?

  1. 使用相對跳轉(zhuǎn)命令 b或bl;

  2. 重定位之前,不可使用絕對地址,不可訪問全局變量/靜態(tài)變量,也不可訪問有初始值的數(shù)組(因為初始值放在rodata里,使用絕對地址來訪問);

  3. 重定位之后,使用ldr pc = xxx,跳轉(zhuǎn)到/runtime地址;

寫位置無關(guān)碼,其實就是不使用絕對地址,判斷有沒有使用絕對地址,除了前面的幾個規(guī)則,最根本的辦法看反匯編。

因此,前面的例子程序使用bl命令相對跳轉(zhuǎn),程序仍在NOR/sram執(zhí)行,要想讓main函數(shù)在SDRAM執(zhí)行,需要修改代碼:?


13.5代碼重定位_代碼重定位與位置無關(guān)碼的評論 (共 條)

分享到微博請遵守國家法律
元阳县| 土默特左旗| 琼中| 阜新市| 泗水县| 东乌珠穆沁旗| 从化市| 盖州市| 大名县| 通化县| 东方市| 德江县| 温宿县| 巴塘县| 伊金霍洛旗| 盖州市| 日照市| 盐池县| 渝中区| 壤塘县| 潮安县| 东源县| 城市| 蓬溪县| 巧家县| 松江区| 平乡县| 原阳县| 桂平市| 磴口县| 伊春市| 集贤县| 连山| 涟源市| 乌鲁木齐县| 沧源| 漳平市| 庄浪县| 常熟市| 秀山| 伊宁市|