自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

程序本身如何知道自身大???這是雞生蛋還是蛋生雞的問題

開發(fā) 前端
一般來說,const 聲明的函數(shù)將放在 RO-data 區(qū)。全局(或局部靜態(tài))未進行初始化(或初始化為0)的變量放在 ZI-data 區(qū),當然棧(stack)也會放在 ZI-data。

 [[351056]]

本文轉(zhuǎn)載自微信公眾號「魚鷹談單片機」,作者魚鷹Osprey。轉(zhuǎn)載本文請聯(lián)系魚鷹談單片機公眾號。

有些情況下,我們可能需要知道程序本身占用的空間大小,一般來說,我們可以從編譯結(jié)果中看到我們的程序到底有多大(不包含 ZI-data 部分):

還可以通過生成的bin文件大小來查看,這個 bin 文件就是不需要經(jīng)過任何轉(zhuǎn)化直接燒錄到 flash 的數(shù)據(jù),當然它也不包含 ZI-data,因為它初始化全是 0,只需要在程序開始時清零即可(該工作由庫函數(shù)自動幫你完成),沒必要保存到 flash中浪費空間。

Bin 文件生成方法(fromelf --bin !L --output hello.bin):

我們可以看一看這些數(shù)據(jù)的空間分布:

一般來說,const 聲明的函數(shù)將放在 RO-data 區(qū)。全局(或局部靜態(tài))未進行初始化(或初始化為0)的變量放在 ZI-data 區(qū),當然棧(stack)也會放在 ZI-data。

MDK的編譯器為我們提供了一些內(nèi)置變量,這些變量是由編譯鏈接之后自動生成的,我們可以直接在程序中獲取,那么有哪些變量,又該如何獲取呢?

據(jù)魚鷹了解,MDK 內(nèi)置了如下變量(有些變量在有些情況下表示相同值):

  1. Image$$ER_IROM1$$Base; 
  2. Image$$ER_IROM1$$Limit; 
  3. Image$$ER_IROM1$$Length;   // 獲取總大小 
  4.  
  5. Load$$LR$$LR_IROM1$$Limit; // 這個和上面的效果一樣 
  6.  
  7. Image$$ER_IROM1$$RO$$Limit;  // 這個和上面的效果一樣 
  8.  
  9. Image$$RW_IRAM1$$Base; 
  10. Image$$RW_IRAM1$$Limit; 
  11. Image$$RW_IRAM1$$Length; 
  12.  
  13. Image$$RW_IRAM1$$ZI$$Base; 
  14. Image$$RW_IRAM1$$ZI$$Limit; 
  15. Image$$RW_IRAM1$$ZI$$Length; 

Image$$ER_IROM1$$Length 對應于 Code + RO Data 的大小,而 base 和 limit 為這段空間的起始和結(jié)束地址。

Image$$RW_IRAM1$$Length 對應于 RW-Data 的大小,而 base 和 limit 為這段空間的起始和結(jié)束地址。

Image$$RW_IRAM1$$ZI$$Length 對應于 ZI-Data(包括STACK) 的大小,而 base 和 limit 為這段空間的起始和結(jié)束地址。

那么我們該如何使用這些變量呢?下面魚鷹提供C語言和匯編兩個版本:

  1. // C語言 
  2. extern int Image$$ER_IROM1$$Base; 
  3.  
  4. unsigned int base = (uint32_t)&Image$$ER_IROM1$$Base 
  5.  
  6. ; 匯編   
  7. IMPORT |Image$$ER_IROM1$$RO$$Base| 
  8. IMPORT |Image$$ER_IROM1$$RO$$Limit| 
  9.  
  10. IMPORT |Image$$RW_IRAM1$$RW$$Base| 
  11. IMPORT |Image$$RW_IRAM1$$RW$$Limit| 
  12.  
  13. IMPORT |Image$$RW_IRAM1$$ZI$$Base| 
  14. IMPORT |Image$$RW_IRAM1$$ZI$$Limit| 

首先使用 extern 關鍵聲明這個外部變量,int 類型。

但是你通過它的使用方式你會發(fā)現(xiàn),這個變量是不可以直接使用的,需要把對它進行取地址,而它的地址才是你想要的數(shù)據(jù)。

事實上,這些內(nèi)置變量本身是不占用空間的的,和用戶聲明的變量是不同的。

我們可以這樣理解,這些變量存放在某個地址空間,這個地址就是它要表示的值(含義),但因為它的特殊性,所以它不占用空間,只能采用取地址的方式獲取它代表的值。

通過這些內(nèi)置變量,原本我們計算 Code + RO-data + RW-Data 的值就可以得到 bin 文件的大小,但當你查看 bin 文件大小之后,你會發(fā)現(xiàn) bin 文件小于該值,這是怎么回事?

通過分析 map 文件我們可以看到如下信息:

你會發(fā)現(xiàn),實際的bin文件包含的 RW 數(shù)據(jù)大小并不是 372,而是 56,也就是說,有一部分數(shù)據(jù)并沒有被包含進 bin 文件用于拷貝(可能和 RW 的數(shù)據(jù)有部分初始值為 0 有關而被壓縮了)。

具體原因,魚鷹也沒搞懂,但是按照之前的變量來看,我們無法準確獲得 bin 文件的大小,只能說獲取到一個比 bin 文件大小稍大的數(shù)字。

原本以為魚鷹不可能獲得準確的 bin 文件大小了,一個偶然的map文件查看,讓魚鷹看到了這么個變量:

好奇的魚鷹對它進行了比較深入的研究,發(fā)現(xiàn)我需要的bin文件(程序)大小就隱藏在這里。

通過分析,魚鷹發(fā)現(xiàn)這個地址包含的8個數(shù)據(jù)含義如下:

通過圖中數(shù)據(jù),減去flash 的基地址,我們就可以獲取到 0x2FE8,即我們 bin 文件實際大小。

而另外兩個函數(shù)地址,原本魚鷹并不知道這些值是干什么用的,還是通過分析 map 文件,才最終確認是兩個函數(shù)的地址,至于到底干什么用的,魚鷹就不是很清楚的,不過看名字也知道應該和變量初始化有關系。

以上就是魚鷹分享的關于程序本身獲取自身大小的知識點,至于你用這些數(shù)據(jù)干啥用那就是你的事情了。

原本魚鷹是準備獲取到bin的大小后通過指定地址的方式在bin文件最后放一些數(shù)據(jù)的,但是這就真的變成雞生蛋蛋生雞的問題了,看來通過內(nèi)置變量的方式是不行了,不知道各位道友有沒有好的方法讓編譯器自動在 bin 文件的后面添加想要的數(shù)據(jù)呢(非第三方工具)?

 

責任編輯:武曉燕 來源: 魚鷹談單片機
相關推薦

2018-08-23 05:07:36

神經(jīng)架構(gòu)深度學習神經(jīng)網(wǎng)絡

2010-04-30 16:08:20

Unix內(nèi)核

2020-10-19 14:05:50

芯片芯片人才芯片行業(yè)

2025-01-16 08:50:33

2020-10-26 11:33:45

編程語言編譯器軟件

2013-07-22 10:35:32

用戶需求技術(shù)創(chuàng)新產(chǎn)品

2016-11-02 00:22:13

數(shù)字化改造數(shù)字化

2019-11-26 09:21:49

區(qū)塊鏈比特幣虛擬貨幣

2012-06-18 15:21:38

Facebook競價廣告

2018-09-27 10:26:12

物聯(lián)網(wǎng)

2018-10-17 09:25:22

2020-04-21 15:54:07

戴爾

2022-04-07 09:29:04

文件系統(tǒng)硬盤操作系統(tǒng)

2012-08-07 09:29:09

程序員編程

2019-11-07 22:00:22

程序員代碼規(guī)范

2013-04-12 02:01:55

微信公眾平臺接口開發(fā)

2019-09-29 10:45:46

C語言CPU編譯器

2021-10-01 00:02:54

CHAR VARCHARMYSQL

2018-12-11 14:07:44

Python分析游戲
點贊
收藏

51CTO技術(shù)棧公眾號