Re: [問題] bss section為啥不占磁碟空間

看板C_and_CPP作者 (purpose)時間12年前 (2012/03/28 15:24), 編輯推噓8(809)
留言17則, 9人參與, 最新討論串3/3 (看更多)
※ 引述《QQ29 (我愛阿蓉)》之銘言: : 很抱歉~這問題不知道是否適合po在這 : 我再看 程式設計師的自我修養 第三章 : 他途中提到一句話 : "bss section是不占用磁碟空間" : 就此令我無法理解... : google的老半天 : 有幾篇文章 : 但他們好像也沒解釋得很清楚也直接下結論 : 請問各位該怎麼理解這句話 : static int x; : 至少他需要記錄bss section 需要占用 "多少"byte這個值吧 : "多少" 難道不用一起寫到elf檔案嗎? : 他是有提到"預留多少空間" 這個預留值再怎樣都要寫到elf檔案吧@@ : 請教各位 : 謝謝

03/28 10:49,
另外問下 data secetion or bss section大小有限制嗎?
03/28 10:49
其實我是覺得這類問題很不重要,理解這個毫無重要目的。 bss 是能幹嘛?也就放未初始化的變數,首先放的人是編譯器,之後進行處理的 也是 linker,以及更後面 OS 的 Loader 等才會去碰他們。 會有這些差異也是這幾位大神出於節省硬碟空間的目的才搞出來, 原則上他們可以不做,而技術上確保他們這樣做沒問題。現在不管有做沒做, 省下那一咪咪的硬碟空間,都不是現代大硬碟時代需要被重視的。 你這輩子根本、幾乎沒機會搞他 bss 了。更何況這還是 ELF 檔,不是 PE 檔, 現在很多人,尤其是大陸人在搞 PE 檔的分析,用 Hex Edit 打開 PE 檔,然後研究其 結構為何,哪個位置應該是存放什麼。 為什麼要研究 PE,因為 PEDIY 有時候其實還蠻有趣的,因為 Windows 大部分程式、軟體 都不開放原始碼,但你有時想破解商業授權、有時是因為作者不維護,想自已解掉 Bug, 在沒有原始碼的情況下,當然只能從成品的 .exe 檔去下手,這些 EXE 檔都嘛 是 PE 格式,所以使得研究 PE 遠比 ELF 有價值很多。 剛剛解掉幾個 Bug,心情還可以,冒著被人說回廢文或出言不遜的惡名,我就跟你一起 討論討論。 我現在沒有 Linux 不能做測試,就光從「程式設計師的自我修養」書上內容來分析吧。 P.58 右下方不是有張圖,這圖除了是畫 ELF 結構以外不可能是其他東西吧? 好,所以 ELF 可以略分成四大部分: File Header, .text section (段), .data 段 以及 .bss 段 在「理論上」檔案內有這四大部分,先不管實際的狀態為何。 在 P.59 最上面文字說:「ELF 檔的開頭是一個 "檔頭",他描述了整個檔的檔案屬性... 等一堆資訊,****還包掛括****一個 Section table,是一個描述個區段的陣列。 區段是指什麼?只能是指 .text, .data, .bss 這些區段吧。 好,所以 Section Table 首先是位於 ELF 的檔案前面部分,他的內容裡有描述 .bss, 但是沒有跟 .bss section 本體放在一起。 按照之前說的 .bsss section 實際上,技術上可以不在檔案內存在(佔空間)。但是這 不表示 .bss header 要跟 .bss 本體一起消失掉,所以你說的 12 這個 Size 記錄,顯 然最有可能是存在這個 Section Table 裡面。 那有現成的分析 ELF 檔案的工具,是 objdump,翻到 P.454 頁,看到說明說 objdump -h: 顯示區段頭表 頭當然是指 header,區段除了是指 .text section 與 .bss section 這些東西以外, 還能是什麼? 再翻到 P.62 可以看到 objdump -h 的使用效果, 可以看到執行結果的格式,應該是一張表沒錯吧。 其第五行是記載 .bss 00000004 00000000 ,,, 這個 00000004 你垂直往上看,應該有看到 Size 吧,那這個內容不就等同於記載 .bss 區段的大小有多大呀。 好,同一行裡面他還有記載一個 00000098 垂直往上看,他寫著 File off 就是 File Offset 也就是中文說的檔案的偏移量 (偏移位置) 無緣無故為什麼要記載這個東西?這其實是為了要快速定位 .bss 這類區段這類 section 在檔案裡面的相對住址,所以從檔案開頭往下數 0x98 個 Bytes 就能找到 .bss 區段 的起始位址... 接下來故事很簡單了,因為 .rodata 的 header 也說其 File off 是 0x98, 起始住址也在偏移 0x98 Bytes 後,這顯然表示說,除非 .bss 根本不佔用空間, 這件事才會發生。 但是佔用 0 Bytes 不就跟 Size 說的 4 相誤了嗎? 其實沒有,因為是「在 ELF 檔案裡面佔用 0 Bytes」,但是當整個 ELF 檔案被載入 到記憶體時,會佔用 4 Bytes。 所謂的載入,其實主要是把檔案的內映射到記憶體上面去,當然實際上沒有完全不動 就照搬過去。 而是挑想要搬的、感興趣的才映射到記憶體,而且位置也可能被亂移,總之就是 到時候記憶體內老子確保你一定有一段連續的位址空間,給你當 .bss 用,而且大小 有 4 Bytes,但是我不保證這個 .bss 就一定要跟 ELF 檔案裡的其他 Sections 相鄰 放在一起,我會隨便放,反正效果有達到就好,你別管細節是怎麼做。 就好像最初 .bss section 本體存在的目的,只是要確保某些變數的初始化內容 能夠被正確保存。 那麼理論上,空間夠多的話,可以完全照放在硬碟的 ELF 檔案裡, 實際上有沒有放是你們的事,只要確保到時候程式運行時,你在記憶體有喬一段 夠大的空間拿來放 .bss 的東西即可。 要達到的目的、目標就這麼簡單,實際上技術細節不重要,你隨便惡搞無所謂。 當老闆的只在乎錢有沒有賺到,手下怎麼做不管。 當程式設計師也應該只在乎編譯器、連結器、載入器,有沒有正確把我們心愛的 那些沒有被初始化的全域變數、static 變數在記憶體擺好位置。 至於這些XX器要怎麼處理,程式設計師不必管,管到 bss 怎麼存實際上是越界的, 這不是你該知道的。 就好像連 1+1 = 2 都不知道,就該死, 知道 1+1 其實 = 2 這又知道太多,同樣該死... -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 124.8.130.6

03/28 16:16, , 1F
感覺你真的解了大bug 心情超嗨
03/28 16:16, 1F

03/28 16:24, , 2F
搞了快一週的,跟一個幾年前放棄的,呵呵
03/28 16:24, 2F

03/28 17:18, , 3F
p 大會的好多啊 ~
03/28 17:18, 3F

03/28 17:57, , 4F
最後一行XDDD
03/28 17:57, 4F

03/28 21:37, , 5F
p 大推!
03/28 21:37, 5F

03/28 23:21, , 6F
請問p大 PE檔案不是MS的東西嗎? 為啥你會說更何況這是ELF
03/28 23:21, 6F

03/28 23:22, , 7F
是因為linux的東西 沒啥好看的嗎 ~不太了解
03/28 23:22, 7F

03/28 23:23, , 8F
說真的...你會用到PE或ELF嗎?如果不會把時間花在更
03/28 23:23, 8F

03/28 23:23, , 9F
有用的地方應該比較有用
03/28 23:23, 9F

03/28 23:26, , 10F
研究 PE 檔是逼不得已的,因為沒有原始碼可以研究
03/28 23:26, 10F

03/28 23:26, , 11F
會弄出 ELF 的城市設計師,九成都會開放原始碼好嗎
03/28 23:26, 11F

03/28 23:27, , 12F
我的意思是指QQ29大大...感覺qq29應該是工作需要讀吧
03/28 23:27, 12F

03/28 23:29, , 13F
當然p大這篇文章寫得很棒!
03/28 23:29, 13F

03/28 23:31, , 14F
我懂你的意思,我也是講給他聽的,沒事
03/28 23:31, 14F

03/28 23:45, , 15F
也不是工作 是自己買來看得...真是深奧
03/28 23:45, 15F

03/29 02:42, , 16F
推p大, 果然看起來很嗨XD
03/29 02:42, 16F

04/20 07:16, , 17F
推 專業文
04/20 07:16, 17F
文章代碼(AID): #1FShok1K (C_and_CPP)
文章代碼(AID): #1FShok1K (C_and_CPP)