我对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