# 2018q3 Homework1 contributed by < [flawless0714](https://github.com/flawless0714) > --- ## 開發工具和規格標準篇 - designated initializer - Array The following two array definition are equivalent. ```C int a[3] = { [2] = 22, [0] = 34}; int a[3] = { 34, 0, 22}; ``` - Structure A struct can also being initialized with method at line 2. ```C= struct core { int cache; int speed; }; struct core core_1 = { .speed = 2400, .cache = 4}; ``` - 心得 認識 designated initializer 後對 struct member 的初始化便利許多,不像以往都是按照順序賦值。 - 提問 想請問老師關於全域變數記憶體配置問題,一個 global 的 struct 內有一個成員有初始化,其他沒有,這樣這個 struct 是不是整個都會配置在 .DATA section 而非 .BSS section ? 因為 struct 內成員的記憶體位置都應為連續的關係。 :::info 先參考 [ Extracting Information from .o and executable binary files](https://www.cs.swarthmore.edu/~newhall/unixhelp/binaryfiles.html) 和 [使用 readelf 和 objdump 解析目標檔案](https://www.jianshu.com/p/863b279c941e),用工具做完實驗,觀察後再來討論 :notes: jserv ::: 測試程式碼: ```C #include <stdio.h> struct fruit { int color; int EXP_date; }; struct fruit apple; struct fruit orange = { .color = 0x00feff }; int main() { printf("color of the fruit: %#08x\n", orange.color); return 0; } ``` 編譯器參數: `$ gcc -o test main.c -Wall`,readelf 參數: `$ readelf -S test`,以下為 readelf 之輸出: (僅擷取部分輸出) ``` Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [22] .got PROGBITS 0000000000200fb8 00000fb8 0000000000000048 0000000000000008 WA 0 0 8 [23] .data PROGBITS 0000000000201000 00001000 0000000000000018 0000000000000000 WA 0 0 8 [24] .bss NOBITS 0000000000201018 00001014 0000000000000010 0000000000000000 WA 0 0 8 [25] .comment PROGBITS 0000000000000000 00001014 0000000000000024 0000000000000001 MS 0 0 1 [26] .symtab SYMTAB 0000000000000000 00001038 0000000000000630 0000000000000018 27 44 8 ``` 由上方 readelf 輸出可得知 .bss section 的大小為10 bytes,而 .data section 的大小為24 bytes,再來我們將==測試程式碼中第十行==的初始化改為 `struct fruit orange;` 時,readelf 輸出則變成如下: ``` Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [22] .got PROGBITS 0000000000200fb8 00000fb8 0000000000000048 0000000000000008 WA 0 0 8 [23] .data PROGBITS 0000000000201000 00001000 0000000000000010 0000000000000000 WA 0 0 8 [24] .bss NOBITS 0000000000201018 00001014 0000000000000018 0000000000000000 WA 0 0 8 [25] .comment PROGBITS 0000000000000000 00001014 0000000000000024 0000000000000001 MS 0 0 1 [26] .symtab SYMTAB 0000000000000000 00001038 0000000000000630 0000000000000018 27 44 8 ``` 本次輸出得知 .bss section 的大小從原本的10 bytes 增加為18 bytes,而 .data section 的大小也從原本的24 bytes 減少為16 bytes,由上下兩輸出可推論出當 struct 內有一個成員被初始化,則整個 struct 都會被配置到 .data section。 再來是 objdump 分析,使用的測驗程式為上面還沒修改過的,編譯器參數為 `gcc -c main.c -Wall`,使用之objdump 參數為 `objdump -s -d -x main.o`,以下為 objdump 輸出中的 SYMBOL TABLE: ``` SYMBOL TABLE: 0000000000000000 l df *ABS* 0000000000000000 main.c 0000000000000000 l d .text 0000000000000000 .text 0000000000000000 l d .data 0000000000000000 .data 0000000000000000 l d .bss 0000000000000000 .bss 0000000000000000 l d .rodata 0000000000000000 .rodata 0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack 0000000000000000 l d .eh_frame 0000000000000000 .eh_frame 0000000000000000 l d .comment 0000000000000000 .comment 0000000000000008 O *COM* 0000000000000008 apple 0000000000000000 g O .data 0000000000000008 orange 0000000000000000 g F .text 0000000000000024 main 0000000000000000 *UND* 0000000000000000 _GLOBAL_OFFSET_TABLE_ 0000000000000000 *UND* 0000000000000000 printf ``` 其中我們可以看到有個 section 叫做 `*COM*`,他的全名為 COMMON SECTION,這個 section 只會出現在 .obj,不會出現在 elf 中,實驗時有發現到假如手動將全域變數初始化為0,則該變數就會被配置在 .bss section 而非 .common section,[Linker and Loader](http://www.becbapatla.ac.in/cse/naveenv/docs/LL1.pdf) 這本書中 `Common blocks`的章節有它的由來與詳細介紹,可能是菜雞的關係...,看完後我還是覺得沒有完全懂它的用途,後來在 [Stackoverflow](https://stackoverflow.com/questions/16835716/bss-vs-common-what-goes-where) 找到比較清楚的了解,它的用途大概是讓全域變數頂著 common block 的名義,在多個使用同個變數名稱的 .obj 在連結時不會有 multiple definition 的錯誤,然後 gcc 還有個 option 可以關掉這個功能, 名稱為 -fno-common,有看到討論說關掉這 option 可以增加效能,但沒有詳細說明,這應該又是另一番故事了。 ## 指標篇 * incomplete type 僅可用於不需要明確大小的地方,如: 指向一個僅宣告而未定義的 struct 的指標。 ###### tags: `sysprog2018`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up