मैं प्रोग्रामिंग सी पर सिगविन विंडोज़ पर हूं। थोड़ा सी प्रोग्रामिंग करने और भाषा के साथ सहज महसूस करने के बाद, मैं हुड के नीचे देखना चाहता था और देखता हूं कि संकलक जो कोड लिखता है उसके लिए क्या कर रहा है।स्विच केस असेंबली स्तर कोड
तो मैं स्विच मामले में बयान से युक्त एक कोड ब्लॉक नीचे लिखा और उन्हें प्रयोग विधानसभा में परिवर्तित कर दिया:
switch(i)
{
case 1:
{
printf("Case 1\n");
break;
}
case 2:
{ printf("Case 2\n");
break;
}
case 3:
{
printf("Case 3\n");
break;
}
case 4:
{
printf("Case 4\n");
break;
}
case 5:
{
printf("Case 5\n");
break;
}
case 6:
{
printf("Case 6\n");
break;
}
case 7:
{
printf("Case 7\n");
break;
}
case 8:
{
printf("Case 8\n");
break;
}
case 9:
{
printf("Case 9\n");
break;
}
case 10:
{
printf("Case 10\n");
break;
}
default:
{
printf("Nothing\n");
break;
}
}
अब एक ही है के लिए परिणामी विधानसभा:
gcc -S foo.c
यहाँ सी स्रोत है :
movl $5, -4(%ebp)
cmpl $10, -4(%ebp)
ja L13
movl -4(%ebp), %eax
sall $2, %eax
movl L14(%eax), %eax
jmp *%eax
.section .rdata,"dr"
.align 4
L14:
.long L13
.long L3
.long L4
.long L5
.long L6
.long L7
.long L8
.long L9
.long L10
.long L11
.long L12
.text
L3:
movl $LC0, (%esp)
call _printf
jmp L2
L4:
movl $LC1, (%esp)
call _printf
jmp L2
L5:
movl $LC2, (%esp)
call _printf
jmp L2
L6:
movl $LC3, (%esp)
call _printf
jmp L2
L7:
movl $LC4, (%esp)
call _printf
jmp L2
L8:
movl $LC5, (%esp)
call _printf
jmp L2
L9:
movl $LC6, (%esp)
call _printf
jmp L2
L10:
movl $LC7, (%esp)
call _printf
jmp L2
L11:
movl $LC8, (%esp)
call _printf
jmp L2
L12:
movl $LC9, (%esp)
call _printf
jmp L2
L13:
movl $LC10, (%esp)
call _printf
L2:
अब, असेंबली में, कोड पहले अंतिम मामले की जांच कर रहा है (यानी मामला 10) पहले। यह बहुत अजीब है। और फिर यह 'i' को 'eax' में कॉपी कर रहा है और मेरे बाहर की चीजें कर रहा है।
मैंने सुना है कि कंपाइलर स्विच..केस के लिए कुछ कूद तालिका लागू करता है। क्या यह कोड क्या कर रहा है? या यह क्या कर रहा है और क्यों? क्योंकि मामलों की कम संख्या के मामले में, कोड कोड के समान उत्पन्न होता है ... और सीढ़ी, लेकिन जब मामलों की संख्या बढ़ जाती है, तो यह असामान्य दिखने वाला कार्यान्वयन देखा जाता है।
अग्रिम धन्यवाद।
कि दुर्भाग्यपूर्ण है कि यह स्ट्रिंग सूचक की एक टेबल देखने के लिए और एक 'कॉल _printf' को अनुकूलित नहीं करता। जीसीसी/क्लैंग/आईसीसी में से कोई भी '-O3' पर भी नहीं करता है। https://godbolt.org/g/JrSwU3 (वे करते अनुकूलन '' puts' को printf', हालांकि, और एक 'एक' call'/'ret' के बजाय jmp' को पूंछ-कॉल का अनुकूलन) –