मैं सीखने की कोशिश कर रहा हूं कि असेंबली प्राथमिक स्तर पर कैसे काम करती है और इसलिए मैं जीसीसी संकलन के आउटपुट के साथ खेल रहा हूं। मैंने एक साधारण कार्यक्रम लिखा जो दो बाइट्स को परिभाषित करता है और अपना योग देता है। पूरे कार्यक्रम इस प्रकार है:जीसीसी असेंबली अनुकूलन - ये समकक्ष क्यों हैं?
int main(void) {
char A = 5;
char B = 10;
return A + B;
}
जब मैं भी अनुकूलन नहीं है का उपयोग कर के साथ इस संकलन:
gcc -O0 -S -c test.c
मैं test.s कि ऐसा दिखाई देता है:
.file "test.c"
.def ___main; .scl 2; .type 32; .endef
.text
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call ___main
movb $5, 15(%esp)
movb $10, 14(%esp)
movsbl 15(%esp), %edx
movsbl 14(%esp), %eax
addl %edx, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.ident "GCC: (GNU) 4.9.2"
अब, यह मानते हुए कि इस कार्यक्रम को एक स्थिर (15) को वापस करने के लिए बहुत आसानी से सरल किया जा सकता है (15) मैं इस कोड का उपयोग करके एक ही फ़ंक्शन करने के लिए हाथ से असेंबली को कम करने में सक्षम हूं:
.global _main
_main:
movl $15, %eax
ret
यह मुझे स्वीकार्य रूप से मामूली कार्य करने के लिए संभवतः कम से कम कोड संभव है (लेकिन मुझे लगता है कि यह गलत हो सकता है) लगता है। क्या यह मेरे सी प्रोग्राम का सबसे "अनुकूलित" संस्करण है?
जीसीसी का प्रारंभिक आउटपुट इतना अधिक वर्बोज़ क्यों है? .cfi_startproc से call__main तक फैले लाइनें क्या करती हैं? __main कॉल क्या करता है? मैं नहीं समझ सकता कि दो घटाव संचालन क्या हैं।
.file "test.c"
.def ___main; .scl 2; .type 32; .endef
.section .text.unlikely,"x"
LCOLDB0:
.section .text.startup,"x"
LHOTB0:
.p2align 4,,15
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
movl $15, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.section .text.unlikely,"x"
LCOLDE0:
.section .text.startup,"x"
LHOTE0:
.ident "GCC: (GNU) 4.9.2"
कौन सा आपरेशन के एक नंबर हटा दिया है लगता है, लेकिन अभी भी सभी लाइनों __main कि अनावश्यक लगते हैं कॉल करने के लिए अग्रणी छोड़ देता है:
भी -O3 को जीसीसी सेट में अनुकूलन के साथमैं इस मिलता है। सभी के लिए .cfi_XXX लाइनें क्या हैं? इतने सारे लेबल क्यों जोड़े गए हैं? क्या करें। सेक्शन, .ident, .def .p2align, आदि इत्यादि करते हैं?
मैं समझता हूँ कि लेबल और प्रतीकों में से कई डीबगिंग के लिए शामिल किए गए हैं, लेकिन इन नहीं छीन या अगर मैं सक्षम जी के साथ संकलन नहीं कर रहा हूँ छोड़ दिया जाना चाहिए?
अद्यतन
इस कोड को संभव कम से कम मात्रा होने के लिए मुझे ऐसा लगता है कह कर स्पष्ट करने के लिए, (लेकिन मैं एहसास काफी गलत हो सकता है) इस प्रदर्शन करने के लिए स्वीकार्य रूप से मामूली कार्य। क्या यह मेरे सी प्रोग्राम का सबसे "अनुकूलित" संस्करण है?
मैं यह सुझाव नहीं दे रहा हूं कि मैं इस कार्यक्रम का एक अनुकूलित संस्करण करने की कोशिश कर रहा हूं या हासिल कर रहा हूं। मुझे एहसास है कि कार्यक्रम बेकार और तुच्छ है। मैं इसे असेंबली सीखने के लिए एक उपकरण के रूप में उपयोग कर रहा हूं और संकलक कैसे काम करता है।
मैंने यह बिट क्यों जोड़ा है इसका मुख्य कारण यह है कि मैं उलझन में हूं कि इस असेंबली कोड का 4 लाइन संस्करण प्रभावी रूप से दूसरों के समान प्रभाव प्राप्त कर सकता है। ऐसा लगता है कि जीसीसी ने "सामान" का बहुत कुछ जोड़ा है जिसका उद्देश्य मैं नहीं समझ सकता।
डीबग। अनुकूलन डीबगर सबसे खराब दुश्मन है। उन सभी अनावश्यक, अच्छी तरह से प्रलेखित लाइनें डिबगिंग असेंबली को डीबगिंग सी के रूप में आसान बनाती हैं। दूसरे प्रश्न के लिए, सी प्रोग्राम सी रन टाइम का उपयोग करते हैं, उन्हें एबीआई का पालन करने की आवश्यकता होती है और ओएस विशिष्ट विशेषताओं का उपयोग कर सकते हैं। –
@WeatherVane मेरा इरादा यह सुझाव देना नहीं था कि इस कार्यक्रम को या तो समझ में आया या किसी भी तरह से उपयोगी था, मैं सिर्फ इसे असेंबली सीखने के लिए एक उपकरण के रूप में उपयोग कर रहा हूं और संकलक कैसे काम करता है। – Kin3TiX
@ Kin3TiX क्षमा करें, मेरी क्रॉस टिप्पणी हटा दी गई है। –