2017-10-15 160 views
0

我對gcc編譯器中的目標代碼生成有疑問。在gcc c編譯器中生成cswtch

在我的程序中,objdump顯示CSWTCH部分已生成。

  1. 你能不能解釋一下什麼樣的C代碼標準要求要生成CSWTCH部分 ?

  2. CSWTCH部分的分配輸出部分是否在.rodata中。

  3. 在哪種情況下將小的數據分配爲CSWTCH的輸出部分。

+1

從我從[這個錯誤報告](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49857)中收集到的信息,它們是在編譯器決定將'switch'語句映射到查找表,並以'.data'結尾。 –

+0

您有*問題*,而不是*疑問* :-)請參閱https://english.stackexchange.com/questions/2429/can-doubt-sometimes-mean-question – torek

回答

0

答案是(1)沒有這樣的標準:這只是一個編譯器用於生成值表的技術; (2)這取決於編譯器,彙編器和鏈接器;和(3)這取決於編譯器,彙編器和鏈接器。

GCC(至少gcc版本5)這裏發出既.section.type指令在x86:

$ cat cswitch.c 
int sw_2 (char x) 
{ 
    switch(x) 
    { 
     case '0': return -1; 
     case '1': return 2; 
     case '2': return 3; 
     case '3': return 5; 
     case '4': return 7; 
     case '5': return 11; 
     case '6': return 13; 
     case '7': return 17; 
     case '8': return 19; 
     case '9': return 23; 
     case 'a':return 29; 
     case 'A':return 29; 
    } 

    return -1; 
} 
$ gcc -Os -S cswitch.c 
$ cat cswitch.s 
     .file "cswitch.c" 
[mass snippage] 
     .section  .rodata 
     .align 32 
     .type CSWTCH.1, @object 
     .size CSWTCH.1, 49 
CSWTCH.1: 

(我發現-Os開關是必需的,以產生在x86查找表隨着-O,我得到一個更典型的跳轉表。)

在這種情況下,.section指令最終應用並將表放入.rodata部分。但這只是一個系統的實現方法 - 編譯器沒有硬性和快速的要求。

請注意,你可以做一個源變換是可能,讓編譯器發出的只讀數據段表:

int sw_3(char x) 
{ 
    const char table['a' - '1'] = { 
     '1' - '1': 2, 
     '2' - '1': 3, 
     '3' - '1': 5, 
     /* ... fill in the remainder as needed */ 
    }; 
    if (x >= '1' && x <= 'A') return table[x - '1']; 
    return -1; 
} 

(這種轉變假定系統使用ASCII或UTF-8或類似的)。然而,即使在這裏,編譯器也可以生成任意的機器碼,只要它產生任何標準所要求的結果。

+0

非常感謝您的幫助。我在我的一個源代碼中遇到了問題。我只有對象代碼。我可以看到生成查找表。但應用於此查找表的.section是.srodata。所以我試圖找到.srodata如何應用於這些.section。也在上面的例子中,而不是在case語句中的預定義字符,如果使用一些const變量。那麼可能會有.srodata的機會。如果上述語句不明確,請糾正我的錯誤 – user210463

+0

在GNU鏈接器腳本中,您可以捕獲任何喜歡的部分,並以任何您喜歡的方式對待它。 '.srodata'部分的目的是爲「小型只讀數據」:通常的想法是將所有小部分集中在一起,並將它們設置爲使用短偏移量尋址指令進行尋址,因此您應該編寫一個鏈接器腳本這樣做(或使用提供的那個)。 – torek