2016-04-24 7 views
5

के साथ तुलना में मैं वर्तमान में असेंबली और सी प्रोग्रामिंग भाषा सीख रहा हूं और मेरे पास इसके बारे में कुछ प्रश्न हैं।असेंबली सी कोड

सी कोड

int arith(int x, int y, int z) { 
    int t1 = x + y; 
    int t2 = z*48; 
    int t3 = t1 & 0xFFFF; 
    int t4 = t2 * t3; 
    return t4; 
} 

विधानसभा कोड

movl 16(%ebp),%eax   z 
leal (%eax,%eax,2), %eax z*3 
sall $4,%eax    t2 = z*48 
movl 12(%ebp),%edx   y 
addl 8(%ebp),%edx   t1 = x+y 
andl $65535,%edx   t3 = t1&0xFFFF 
imull %edx,%eax    Return t4 = t2*t3 
इसके बजाय लील का उपयोग कर और फिर 4 से स्थानांतरण 48 से जेड गुणा करने के लिए, मैं सिर्फ $ 48,% eax imull इस्तेमाल कर सकते हैं की

?

इसके अलावा, यह कई बार% edx रजिस्टर का उपयोग कर रहा है। क्या इसका मतलब है कि टी 1 ओवरराइट किया जा रहा है? दूसरे शब्दों में, क्या मैं अभी भी टी 4 से पहले टी 1 को पुनः प्राप्त कर पाऊंगा यदि मैं चाहता था?

+1

हां, नहीं (चर 'टी 1' को अनुकूलित किया गया है), और नहीं। आखिरी प्रश्न' x + y' की गणना की जाती है लेकिन कभी नहीं सहेजी जाती है। _EDX_ के पास 'एडीएल 8 (% ईबीपी),% edx' के बाद मान' x + y' था लेकिन निर्देश 'और $ 65535,% edx' इसे नष्ट कर देता है। यदि आपने _EDX_ को _ECX_ जैसे किसी एडीएल 8 (% ईबीपी),% edx' के बाद स्थानांतरित किया है तो आपको अभी भी गणना के x + y भाग तक पहुंच होगी। –

+0

कूल। सी कोड वास्तव में इस तरह के दृश्यों के पीछे अनुवादित किया जाएगा कि यह प्रत्येक चर को अपने रजिस्टर में स्टोर नहीं करेगा? – Dylan

+2

यदि इसकी आवश्यकता नहीं है तो नहीं। यह एक अनुकूल संकलक की शक्ति है। – usr2564301

उत्तर

2

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

अपने पहले प्रश्न का उत्तर देने के लिए, तकनीकी रूप से काम करेगा, लेकिन एक बार फिर संकलक कई अनुकूलन करता है। इसलिए जब यह इमुल का उपयोग करने के लिए अधिक सहज महसूस कर सकता है, तो संकलक ने निर्धारित किया कि लील और सल अधिक कुशल है। संपादित करें: मैं बस यह इंगित करना चाहता हूं कि जब संभव हो तो इमुल के बजाय बिट शिफ्ट ऑपरेटरों का लगभग हमेशा उपयोग किया जाता है। बिट स्थानांतरण स्थानांतरण सीपीयू के लिए बहुत सस्ता है क्योंकि यह सचमुच कुछ गणितीय ऑपरेशन करने की कोशिश करने के बजाय थोड़ा मूल्य बदल रहा है जो अधिक CPU समय ले सकता है।

अब "ओवरराइटिंग" टी 1 के संबंध में। असेंबली में आपके प्रोग्राम चर के बारे में कोई जानकारी नहीं है - यह सब जानता है कि इसे कुछ मूल्यों पर कुछ संचालन करने की आवश्यकता है। जबकि असेंबली टी 1-4 स्टोर करने के लिए संभावित रूप से 4 अलग-अलग रजिस्टरों का उपयोग कर सकती है, संकलक ने यह निर्धारित किया कि यह अनावश्यक था और आपको केवल सभी मानों के लिए 2 रजिस्टरों की आवश्यकता है। यदि आप इसके बारे में सोचते हैं, तो इसे समझना चाहिए। आपका फ़ंक्शन कोड की कुछ पंक्तियों तक कम किया जा सकता है। जाहिर है कि यह एक अच्छा विचार नहीं है क्योंकि इससे पढ़ना असंभव हो जाएगा, लेकिन असेंबली को "पठनीय" होने के लिए तैयार नहीं किया गया है। यदि आप अपने कार्यक्रम में वापस गए और टी 4 लौटने से पहले टी 1 के साथ कुछ अन्य ऑपरेशन किया, तो आप देख सकते हैं कि आपकी असेंबली पहले से अलग है और यह कि किसी अन्य रजिस्टर का उपयोग कर सकती है, इस पर निर्भर करता है कि मूल्य का उपयोग कैसे किया जाता है।

यदि आप वास्तव में असेंबली में अपने प्रोग्राम का बेयरबोन संस्करण चाहते हैं, तो संकलक अनुकूलन को बंद करने के लिए -ऑग ध्वज के साथ संकलित करें। यह अभी भी आपके कोड से बिल्कुल मेल नहीं खा सकता है, लेकिन यह आपके लिए यह समझना आसान हो सकता है कि क्या हो रहा है।

+1

धन्यवाद। जो कुछ भी आपने कहा वह मुझे समझ में आया। यह अच्छा है कि यह इस तरह के दृश्यों के पीछे कैसे अनुकूलित करता है। – Dylan

+1

निर्देश अनुकूलन जानकारी का एक अच्छा स्रोत इस [एग्नेर फॉग दस्तावेज़] (http: //www.agner) में पाया जा सकता है।org/अनुकूलन/instruction_tables.pdf)। आर्किटेक्चर के आधार पर LEAL भी एएलयू तक नहीं पहुंच सकता है। कुछ x86 आर्किटेक्चर पर यह एजीई के हिस्से के रूप में किया जाता है। –

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