我對gcc編譯器中的目標代碼生成有疑問。在gcc c編譯器中生成cswtch
在我的程序中,objdump顯示CSWTCH
部分已生成。
你能不能解釋一下什麼樣的C代碼標準要求要生成
CSWTCH
部分 ?CSWTCH
部分的分配輸出部分是否在.rodata
中。在哪種情況下將小的數據分配爲
CSWTCH
的輸出部分。
我對gcc編譯器中的目標代碼生成有疑問。在gcc c編譯器中生成cswtch
在我的程序中,objdump顯示CSWTCH
部分已生成。
你能不能解釋一下什麼樣的C代碼標準要求要生成CSWTCH
部分 ?
CSWTCH
部分的分配輸出部分是否在.rodata
中。
在哪種情況下將小的數據分配爲CSWTCH
的輸出部分。
答案是(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或類似的)。然而,即使在這裏,編譯器也可以生成任意的機器碼,只要它產生任何標準所要求的結果。
非常感謝您的幫助。我在我的一個源代碼中遇到了問題。我只有對象代碼。我可以看到生成查找表。但應用於此查找表的.section是.srodata。所以我試圖找到.srodata如何應用於這些.section。也在上面的例子中,而不是在case語句中的預定義字符,如果使用一些const變量。那麼可能會有.srodata的機會。如果上述語句不明確,請糾正我的錯誤 – user210463
在GNU鏈接器腳本中,您可以捕獲任何喜歡的部分,並以任何您喜歡的方式對待它。 '.srodata'部分的目的是爲「小型只讀數據」:通常的想法是將所有小部分集中在一起,並將它們設置爲使用短偏移量尋址指令進行尋址,因此您應該編寫一個鏈接器腳本這樣做(或使用提供的那個)。 – torek
從我從[這個錯誤報告](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49857)中收集到的信息,它們是在編譯器決定將'switch'語句映射到查找表,並以'.data'結尾。 –
您有*問題*,而不是*疑問* :-)請參閱https://english.stackexchange.com/questions/2429/can-doubt-sometimes-mean-question – torek