日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

编译过程中的链接地址对最终编译镜像文件的影响

發(fā)布時間:2024/7/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 编译过程中的链接地址对最终编译镜像文件的影响 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

MDK和交叉編譯工具編譯時都會指定程序的下載的地址(其實就是告訴程序它將在那個地址上開始執(zhí)行),這有什么意義嗎?

  其實這么設計有原因的,因為這里涉及到全局變量和全局函數(shù)指針的地址問題,加入當你在編譯時指定編譯器這段程序會在0x0c000000地址上運行,因此全局變量和全局函數(shù)指針就會從0x0c000000上開始分配地址,此時如果你把這段程序燒錄到0x0c000000地址上運行,變量的訪問和指令存取不會有人任何問題,但是如果你將程序下載到0x00000000上運行時,在程序會在訪問全局變量時,實際上這個變量地址分配的地址是0x00000001但是,因為你編譯是連接地址不是0x00000000所以程序會到0x0c000001去讀取這個變量,此時就會讀到一個錯誤的值。對于函數(shù)指針也是相同的道理,但此時指令就跑飛了。

ARM處理器上的用處(相對跳轉和絕對跳轉)

絕對跳轉:就是執(zhí)行了這一條指令之后就會跳轉到絕對跳轉的指令中的地址去執(zhí)行。
相對跳轉:從當前地址偏移一定的偏移地址去執(zhí)行一個程序。
將被編譯到0xC0000000地址的代碼放到0x00000000地址開始執(zhí)行,如果它們只使用順序執(zhí)行或者相對跳轉執(zhí)行方式就可以正常運行(未使用全局變量和全局函數(shù)指針),但如果使用了絕對尋址,那么程序就跑飛了。
我們參照下面這段偽代碼來說明這個情況。

指令編號 指令功能 指令1 :順序執(zhí)行 指令2 :順序執(zhí)行 指令3 :相對跳轉到指令5 指令4 :順序執(zhí)行 指令5 :順序執(zhí)行 指令6 :絕對跳轉到指令8 指令7 :順序執(zhí)行 指令8 :順序執(zhí)行

在編譯、鏈接的時候,這段程序被告知放在0xC0000000地址空間,編譯后燒錄到0x00000000結果在存儲設備中的存放結果為(每條指令以4字節(jié)計算):

指令地址 指令編號 指令功能 下條指令地址0x00000000 指令1: 順序執(zhí)行 當前地址+4 0x00000004 指令2: 順序執(zhí)行 當前地址+4 0x00000008 指令3: 相對跳轉到指令5 當前地址+8 0x0000000C 指令4: 順序執(zhí)行 當前地址+4 0x00000010 指令5: 順序執(zhí)行 當前地址+4 0x00000014 指令6: 絕對跳轉到指令8 0xC000001C 0x00000018 指令7: 順序執(zhí)行 當前地址+4 0x0000001C 指令8: 順序執(zhí)行 當前地址+4

程序從0x00000000開始運行直到第五條指令都是不會出錯的,但是當執(zhí)行完指令6后程序就會跑飛了,因為指令6是一條絕對跳轉的指令但0xC000001C空間沒有代碼,這樣程序就跑飛了。但當這段程序被放在0xC0000000起始空間時,開始執(zhí)行指令1,然后采用相對尋址的方法就可以運行到指令6,在指令6執(zhí)行時執(zhí)行絕對尋址的方法從0xC0000014正確跳轉到指令8所在的0xC000001C位置,這段代碼運行正常。(參考博客:http://blog.sina.com.cn/s/blog_908da74601011bg6.html)

如圖:

MDK編譯后的STM32工程 map文件簡單分析

只看map文件中有用的部分:

Code為程序代碼部分
RO-data 表示 程序定義的常量const temp;
RW-data 表示 已初始化的全局變量
ZI-data 表示 未初始化的全局變量

Program Size: Code="18248" RO-data=320 RW-data=260 ZI-data=3952

Code, RO-data,RW-data ............flash
RW-data, ZIdata...................RAM (內(nèi)存)

?

存儲Size:

RO size: Code + RO_data

RW size: RW_data + ZI_data

ROM (minimum)size = Code + RO_data + RW_data (即燒/下載程序到FLASH/ROM時,所占用的最小空間)

Total ROM Size (Code + RO Data + RW Data)這樣所寫的程序占用的ROM的字節(jié)總數(shù),也就是說程序所下載到ROM flash 中的大小。為什么Rom中還要存RW,因為掉電后RAM中所有數(shù)據(jù)都丟失了,每次上電RAM中的數(shù)據(jù)是被重新賦值的,每次這些固定的值就是存儲在Rom中的,為什么不包含ZI段呢,是因為ZI數(shù)據(jù)都是0,沒必要包含,只要程序運行之前將ZI數(shù)據(jù)所在的區(qū)域一律清零即可。包含進去反而浪費存儲空間。

RAM size: RW Data + ZI Data (即程序運行的時,RAM使用的空間)

一個ARM程序包含3部分:RO段,RW段和ZI段
RO是程序中的指令和常量
RW是程序中的已初始化變量
ZI是程序中的零初始化的變量
由以上3點說明可以理解為:
RO就是readonly,
RW就是read/write,
ZI就是zero

完事,今天好冷哎!

轉載于:https://www.cnblogs.com/w-smile/p/10073790.html

總結

以上是生活随笔為你收集整理的编译过程中的链接地址对最终编译镜像文件的影响的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。