2015-07-01 12 views
8

मैं सीखने की कोशिश कर रहा हूं कि असेंबली प्राथमिक स्तर पर कैसे काम करती है और इसलिए मैं जीसीसी संकलन के आउटपुट के साथ खेल रहा हूं। मैंने एक साधारण कार्यक्रम लिखा जो दो बाइट्स को परिभाषित करता है और अपना योग देता है। पूरे कार्यक्रम इस प्रकार है:जीसीसी असेंबली अनुकूलन - ये समकक्ष क्यों हैं?

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 लाइन संस्करण प्रभावी रूप से दूसरों के समान प्रभाव प्राप्त कर सकता है। ऐसा लगता है कि जीसीसी ने "सामान" का बहुत कुछ जोड़ा है जिसका उद्देश्य मैं नहीं समझ सकता।

+1

डीबग। अनुकूलन डीबगर सबसे खराब दुश्मन है। उन सभी अनावश्यक, अच्छी तरह से प्रलेखित लाइनें डिबगिंग असेंबली को डीबगिंग सी के रूप में आसान बनाती हैं। दूसरे प्रश्न के लिए, सी प्रोग्राम सी रन टाइम का उपयोग करते हैं, उन्हें एबीआई का पालन करने की आवश्यकता होती है और ओएस विशिष्ट विशेषताओं का उपयोग कर सकते हैं। –

+0

@WeatherVane मेरा इरादा यह सुझाव देना नहीं था कि इस कार्यक्रम को या तो समझ में आया या किसी भी तरह से उपयोगी था, मैं सिर्फ इसे असेंबली सीखने के लिए एक उपकरण के रूप में उपयोग कर रहा हूं और संकलक कैसे काम करता है। – Kin3TiX

+0

@ Kin3TiX क्षमा करें, मेरी क्रॉस टिप्पणी हटा दी गई है। –

उत्तर

6

आप एक एएसएम-नौसिखिया सवाल है कि कोई टिप्पणी नहीं के साथ कुछ बुरा कोड की सिर्फ एक कोड-डंप, और एक बहुत साधारण सी समस्या नहीं था पूछने के लिए धन्यवाद, Kin3TiX,। :)

एक तरीका के रूप में, अपने पैरों एएसएम के साथ गीला हो रहा main के अलावा अन्य कार्यों के साथ काम करने की सलाह देते हैं चाहते हैं। जैसे केवल एक फ़ंक्शन जो दो पूर्णांक तर्क लेता है, और उन्हें जोड़ता है। फिर संकलक इसे अनुकूलित नहीं कर सकता है। आप अभी भी इसे स्थिरांक के साथ तर्क के रूप में कॉल कर सकते हैं, और यदि यह main से एक अलग फ़ाइल में है, तो यह रेखांकित नहीं होगा, इसलिए आप इसके माध्यम से एकल-चरण भी कर सकते हैं।

main संकलित करते समय एएसएम स्तर पर क्या हो रहा है, यह समझने के लिए कुछ लाभ है, लेकिन एम्बेडेड सिस्टम के अलावा, आप कभी भी एएसएम में अनुकूलित आंतरिक लूप लिखने जा रहे हैं। आईएमओ, अगर आप इसे बाहर निकालने के लिए नहीं जा रहे हैं तो एएसएम का उपयोग करके थोड़ा सा बिंदु है। अन्यथा आप शायद स्रोत से कंपाइलर आउटपुट को हरा नहीं देंगे जो पढ़ने के लिए बहुत आसान है।

कंपाइलर आउटपुट को समझने के लिए अन्य युक्तियाँ:
gcc -S -fno-stack-check -fverbose-asm के साथ संकलित करें। प्रत्येक निर्देश के बाद टिप्पणियां अक्सर उस लोड के लिए क्या अनुस्मारक की याद दिलाती हैं। बहुत जल्द यह D.2983 जैसे नामों के साथ अस्थायी गड़बड़ी में गिरावट आई है, लेकिन
movq 8(%rdi), %rcx # a_1(D)->elements, a_1(D)->elements जैसे कुछ आपको एबीआई संदर्भ के लिए एक राउंड-ट्रिप बचाएंगे, यह देखने के लिए कि %rdi में कौन सा फ़ंक्शन तर्क आता है, और कौन सा स्ट्रक्चर सदस्य ऑफ़सेट 8 पर है।

.cfi_startproc से call__main तक फैली लाइनें क्या करती हैं?

_main: 
LFB0: 
    .cfi_startproc 
    pushl %ebp 
    .cfi_def_cfa_offset 8 
    .cfi_offset 5, -8 
    movl %esp, %ebp 
    .cfi_def_cfa_register 5 

के रूप में अन्य लोगों ने कहा, .cfi सामान की जानकारी डीबग कर रहा है। यह सामान है कि strip आपकी बाइनरी से हटा देगा, या अगर आप -g का उपयोग नहीं करते हैं तो यह पहले स्थान पर नहीं होगा। आईडीके -g के बिना -S आउटपुट में वे क्यों हैं। अक्सर मैं gcc -S के बजाय objdump -d आउटपुट से एएसएम देखता हूं। आम तौर पर क्योंकि मैं निष्पादन योग्य बेंचमार्क कर सकता हूं और gcc कई बार आह्वान करने की आवश्यकता के बिना, इसके एएसएम को देख सकता हूं।

%ebp को धक्का देने वाली सामग्री और फिर फ़ंक्शन एंट्री पर स्टैक पॉइंटर के मान पर सेट करने के लिए इसे "स्टैक फ्रेम" कहा जाता है। यही कारण है कि %ebp आधार सूचक कहा जाता है। यदि आप के साथ संकलित करते हैं, तो ये insns वहां नहीं होंगे, जो कोड के साथ काम करने के लिए एक अतिरिक्त रजिस्टर देता है। (यह 32 बिट x86 के लिए बहुत बड़ा है, क्योंकि यह आपको 6 से 7 regs तक ले जाता है। (%esp अभी भी स्टैक पॉइंटर होने के कारण जुड़ा हुआ है; इसे अस्थायी रूप से एक एक्सएमएम या एमएमएक्स reg में चिपका रहा है और फिर इसका उपयोग अन्य जीपी reg के रूप में संभव है, लेकिन अपने कोड डिबग करने के लिए मुश्किल हो जाएगा!)

ret से पहले leave अनुदेश भी इस स्टैक फ्रेम सामान का हिस्सा है।

मैं फ्रेम संकेत के उद्देश्य पर पूरी तरह स्पष्ट नहीं कर रहा हूँ। डिबग प्रतीकों के साथ, आप कॉल स्टैक को के साथ भी ठीक कर सकते हैं, और यह amd64 के लिए डिफ़ॉल्ट है। (amd64 एबीआई के पास स्टैक के लिए संरेखण आवश्यकताएं हैं, अन्य तरीकों से बहुत बेहतर है। उदाहरण के लिए स्टैक पर बजाय regs में args गुजरता है।)

andl $-16, %esp 
    subl $16, %esp 

and, एक 16-बाइट सीमा के ढेर संरेखित करता है जिस पर वह पहले था की परवाह किए बिना। sub इस फ़ंक्शन के लिए स्टैक पर 16 बाइट्स आरक्षित करता है। (ध्यान दें कि यह कैसे अनुकूलित संस्करण से लापता है, क्योंकि यह किसी भी चर की स्मृति भंडारण के लिए कोई आवश्यकता दूर अनुकूलित करता है।)

call ___main 

_main (एएसएम नाम = __main) शायद उस कंस्ट्रक्टर्स कॉल एक जीसीसी रन-टाइम पुस्तकालय समारोह है उन चीज़ों के लिए जिनकी आवश्यकता है। शायद लाइब्रेरी सेटअप सामान, और यह हो सकता है कि आपके किसी भी वैश्विक/स्थैतिक चर के लिए कन्स्ट्रक्टर कहलाए जाएं।(यह old mailing list message इंगित करता है _main रचनाकारों के लिए है, लेकिन यह मुख्य रूप से इसे प्लेटफ़ॉर्म पर कॉल करने की आवश्यकता नहीं है जो इसे कॉल करने के लिए स्टार्टअप कोड प्राप्त करने का समर्थन करता है। शायद i386 में यह नहीं है, केवल amd64?) संपादित करें: आपने कहा टिप्पणी करें कि यह साइगविन से आया था। इससे यह समझा जाएगा, क्योंकि सिगविन को गैर-ईएलएफ .exes बनाना है।

movb $5, 15(%esp) 
    movb $10, 14(%esp) 
    movsbl 15(%esp), %edx 
    movsbl 14(%esp), %eax 
    addl %edx, %eax 
    leave 
    ret 

क्यों जीसीसी के प्रारंभिक उत्पादन इतना अधिक वर्बोज़ है?

ऑप्टिमाइज़ेशन सक्षम किए बिना, जीसीसी मानचित्र सी कथन शब्दशः यथासंभव यथासंभव संभवतः। कुछ और करने से अधिक संकलन समय लगेगा। इस प्रकार, movb आपके दो चर के लिए प्रारंभकर्ताओं से है। रिटर्न वैल्यू को दो लोड करके गणना की जाती है (साइन एक्सटेंशन के साथ, क्योंकि हमें सी कोड के अर्थशास्त्र से लिखे जाने के लिए, जोड़ के पहले int में अपवर्तन करने की आवश्यकता होती है, जहां तक ​​अतिप्रवाह है)।

मुझे नहीं पता कि दो घटाव संचालन क्या हैं।

केवल एक sub निर्देश है। __main पर कॉल करने से पहले, यह फ़ंक्शन के चर के लिए स्टैक पर स्थान सुरक्षित रखता है। आप किस अन्य उप के बारे में बात कर रहे हैं?

क्या करें। सेक्शन, .ident, .def .p2align, आदि आदि क्या करते हैं?

manual for the GNU assembler देखें। जानकारी पृष्ठों के रूप में भी स्थानीय रूप से उपलब्ध: info gas चलाएं।

.ident और .def: ऐसा लगता है कि जीसीसी ने ऑब्जेक्ट फ़ाइल पर अपना टिकट डाला है, ताकि आप यह बता सकें कि कंपाइलर/असेंबलर ने इसे किस प्रकार बनाया है। प्रासंगिक नहीं है, इन्हें अनदेखा करें।

.section: निर्धारित करता है ELF वस्तु का क्या अनुभाग में, सभी निम्नलिखित निर्देशों या डेटा निर्देशों (जैसे .byte 0x00) में जाने से बाइट्स फ़ाइल अगले .section कोडांतरक निर्देश जब तक। या तो code (केवल पढ़ने योग्य, साझा करने योग्य), data (प्रारंभिक पढ़ने/लिखने का डेटा, निजी), या bss (ब्लॉक स्टोरेज सेगमेंट। शून्य-प्रारंभिक, ऑब्जेक्ट फ़ाइल में कोई स्थान नहीं लेता है)।

.p2align: 2 संरेखण की शक्ति। वांछित संरेखण तक एनओपी निर्देशों के साथ पैड। .align 16.p2align 4 जैसा ही है। लक्ष्य को गठबंधन करते समय जंप निर्देश तेजी से होते हैं, 16 बी के भाग में निर्देश लाने के कारण, पृष्ठ सीमा पार नहीं करते हैं, या केवल कैश-लाइन सीमा पार नहीं करते हैं। (32 बी संरेखण प्रासंगिक है जब कोड पहले से ही इंटेल सैंडब्रिज के यूओपी कैश में है और बाद में।) Agner Fog's docs देखें, उदाहरण के लिए।

कारण है कि मैं इस बिट जोड़ा की कोर वर्णन करने के लिए कारण है कि मैं उलझन में है कि इस विधानसभा कोड के 4 लाइन संस्करण को प्रभावी ढंग से दूसरों के रूप में एक ही प्रभाव को प्राप्त कर सकते है। ऐसा लगता है कि जीसीसी ने "सामान" के बहुत सारे को जोड़ा है जिसका उद्देश्य मैं नहीं समझ सकता।

अपने आप में एक फ़ंक्शन में रुचि का कोड रखें। main के बारे में बहुत सी चीजें विशेष हैं।

आप सही है कि एक mov -immediate और एक ret सब समारोह लागू करने की जरूरत है कर रहे हैं, लेकिन जीसीसी जाहिरा तौर पर तुच्छ पूरे कार्यक्रमों पहचानने और main के ढेर फ्रेम या _main करने के लिए कॉल को छोड़ते हुए के लिए शॉर्टकट नहीं है । >। <

अच्छा सवाल, हालांकि। जैसा कि मैंने कहा, बस उस बकवास को अनदेखा करें और केवल उस छोटे से हिस्से के बारे में चिंता करें जिसे आप अनुकूलित करना चाहते हैं।

0

मुझे लगता है कि भाग सिर्फ एक निश्चित पैटर्न है जो 16-बाइट गठबंधन स्टैक सेट करता है और सीएफआई exception frame संबंधित हैंडलिंग संबंधित है।के बाद से है कि एक वैश्विक अनुकूलन है, क्योंकि मुख्य अन्य संकलन इकाइयों में कार्यों कॉल कर सकते हैं

निर्धारण है कि उन किसी भी मुख्य() के लिए आवश्यक नहीं कर रहे हैं मुश्किल है।

और यह शायद नहीं सार्थक समय इस तुच्छ और काफी बेकार मामले अनुकूलन करने के लिए खर्च कर रहा है।

यदि आप अन्यथा महसूस करते हैं, तो आप हमेशा इस तरह के अनुकूलन पर काम करना शुरू कर सकते हैं और इसे जीसीसी में जमा कर सकते हैं।

+1

एक अपवाद फ्रेम सी ++ की तरह लगता है, क्योंकि सी में अपवाद नहीं हैं। लेकिन यह वास्तव में दोनों भाषाओं के लिए एक आम टेम्पलेट हो सकता है। – Olaf

+0

यह सुझाव देने की कोशिश नहीं कर रहा कि मैं इस उदाहरण को "अनुकूलित" करने में सक्षम था ... बस यह समझने की कोशिश कर रहा हूं कि मैं उस असेंबली को इतनी कम लाइनों पर क्यों रोक सकता हूं और अभी भी यह काम कर रहा है। यह मुझे आश्चर्यचकित करता है कि वहां अन्य सभी चीजें क्या कर रही हैं, जो मेरे प्रश्न का क्रूक्स था। – Kin3TiX

+0

फिर अलग-अलग फ़ंक्शंस में रुचि रखने वाले सभी कोड डालें, और उच्च अनुकूलन के साथ संकलित करें। स्टार्टअप और मुख्य कोड के लिए कभी-कभी अन्य नियम और ट्रेडऑफ मौजूद होते हैं और यह पता चलता है कि क्या होता है, जैसा कि आपने पाया था। –

1

पहले, CFI सामान डीबगिंग उद्देश्यों (और, सी ++ में, अपवाद हैंडलिंग) के लिए होती है। यह डीबगर को बताता है कि स्टैक फ्रेम प्रत्येक निर्देश पर कैसा दिखता है, ताकि डीबगर प्रोग्राम के चर के राज्य को पुनर्निर्माण कर सके। जिनके परिणामस्वरूप निष्पादन योग्य बयान नहीं होते हैं, और प्रोग्राम के रनटाइम प्रदर्शन पर शून्य प्रभाव पड़ता है।

मैं नहीं जानता कि क्या __main करने के लिए कॉल वहाँ क्या कर रही है - मेरी जीसीसी कि नहीं करता है। वास्तव में, मेरी जीसीसी (4.9.2) मुझे देता है gcc test.c -S -O1 के लिए निम्नलिखित:

.section __TEXT,__text_startup,regular,pure_instructions 
    .globl _main 
_main: 
LFB0: 
    movl $15, %eax 
    ret 
LFE0: 
    .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support 
EH_frame1: 
    .set L$set$0,LECIE1-LSCIE1 
    .long L$set$0 
LSCIE1: 
    .long 0 
    .byte 0x1 
    .ascii "zR\0" 
    .byte 0x1 
    .byte 0x78 
    .byte 0x10 
    .byte 0x1 
    .byte 0x10 
    .byte 0xc 
    .byte 0x7 
    .byte 0x8 
    .byte 0x90 
    .byte 0x1 
    .align 3 
LECIE1: 
LSFDE1: 
    .set L$set$1,LEFDE1-LASFDE1 
    .long L$set$1 
LASFDE1: 
    .long LASFDE1-EH_frame1 
    .quad LFB0-. 
    .set L$set$2,LFE0-LFB0 
    .quad L$set$2 
    .byte 0 
    .align 3 
LEFDE1: 
    .subsections_via_symbols 

और आप उस पर विचार करेंगे, _main ठीक दो-अनुदेश अनुक्रम आप की उम्मीद है। (__eh_frame सामान एक अलग प्रारूप में अधिक डिबगिंग जानकारी है)।

5

.cfi (कॉल फ्रेम जानकारी) निर्देश gas (जीएनयू एस्सेबलर) में मुख्य रूप से डिबगिंग के लिए उपयोग किए जाते हैं। वे डीबगर को ढेर को खोलने की अनुमति देते हैं। उन्हें अक्षम करने के लिए, जब आप संकलन ड्राइवर -fno-asynchronous-unwind-tables का आह्वान करते हैं तो आप निम्न पैरामीटर का उपयोग कर सकते हैं।

आप सामान्य रूप में संकलक के साथ खेलना चाहते हैं, तो आपको निम्न संकलन ड्राइवर मंगलाचरण आदेश -o <filename.S> -S -masm=intel -fno-asynchronous-unwind-tables <filename.C> उपयोग कर सकते हैं या सिर्फ godbolt's interactive compiler

+0

इंटरैक्टिव कंपाइलर अविश्वसनीय रूप से सहायक है। विशेष रूप से, रंगीन सुविधा ने मुझे सीधे यह देखने की अनुमति दी है कि मेरे स्रोत की रेखाओं से सीधे कौन से असेंबली निर्देश उत्पन्न होते हैं। अन्य उत्तरों ने बाद में उन सभी अन्य "सामान" को अलग करने में मदद की जो वहां समाप्त होते हैं। – Kin3TiX

+0

@ Kin3TiX खुशी है कि मैं मदद की है। – NlightNFotis

1

का उपयोग -o0 विकल्प 0 नाम की एक फ़ाइल को आउटपुट निर्देश देता है। हो सकता है कि आप ऑप्टिमाइज़ेशन लेवल (जो पूंजी ) है ?: जो ऑप्टिमाइज़ेशन को अक्षम करता है।

मुझे समझ नहीं आता क्यों ____main के लिए एक कॉल होगा जब तक कि यह कुछ नकल करते या शौकीन पर्यावरण के लिए तैयार की गई थी है। जब मैं gcc -O0 -c -S t.c साथ संकलन, मैं मिलता है:

 .file "t.c" 
     .text 
.globl main 
     .type main, @function 
main: 
.LFB0: 
     .cfi_startproc 
     pushq %rbp 
     .cfi_def_cfa_offset 16 
     .cfi_offset 6, -16 
     movq %rsp, %rbp 
     .cfi_def_cfa_register 6 
     movb $5, -2(%rbp) 
     movb $10, -1(%rbp) 
     movsbl -2(%rbp), %edx 
     movsbl -1(%rbp), %eax 
     leal (%rdx,%rax), %eax 
     leave 
     .cfi_def_cfa 7, 8 
     ret 
     .cfi_endproc 
.LFE0: 
     .size main, .-main 
     .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)" 
     .section  .note.GNU-stack,"",@progbits 

शायद आप अनुकूलन का एक उच्च स्तरीय उम्मीद कर रहे थे?

 .file "t.c" 
     .text 
     .p2align 4,,15 
.globl main 
     .type main, @function 
main: 
.LFB0: 
     .cfi_startproc 
     movl $15, %eax 
     ret 
     .cfi_endproc 
.LFE0: 
     .size main, .-main 
     .ident "GCC: (GNU) 4.4.7 20120313 (Red Hat 4.4.7-11)" 
     .section  .note.GNU-stack,"",@progbits 

डिबग जानकारी के अलावा, इसके बारे में के रूप में कम के रूप में यह हो सकता है: यह है कि मैं क्या gcc -O3 -c -S t.c साथ हो रही है। एक ही कोड gcc -O2 -c -S t.c और gcc -O1 -c -S t.c के लिए बनाया गया है। यही है, मामूली अनुकूलन संकलन समय पर सभी स्थिरांक का मूल्यांकन करता है।

+0

मेरे पास पूंजी-ओ ... था? भले ही, मुझे लगता है कि आपका जवाब मुझे __main बताता है। मैंने इसे सिगविन पर चलाया (काम पर इसलिए मैं अपने लिनक्स बॉक्स एटीएम पर नहीं हूं), ताकि एक नकली या घुमावदार वातावरण पर चलने के बारे में आपकी टिप्पणी का समर्थन किया जा सके। – Kin3TiX

संबंधित मुद्दे