क्या यह है कि C में + ऑपरेटर कैसे लागू किया जाता है?


79

जब इस तरह के रूप में कैसे आदिम ऑपरेटरों को समझने +, -, *और /सी में लागू किया जाता है, मैं से निम्नलिखित स्निपेट मिला एक दिलचस्प जवाब

ऐसा लगता है कि यह फ़ंक्शन दर्शाता है कि +पृष्ठभूमि में वास्तव में कैसे काम करता है। हालाँकि, इसे समझना मेरे लिए बहुत उलझन की बात है। मेरा मानना ​​था कि लंबे समय तक संकलक द्वारा उत्पन्न विधानसभा निर्देशों का उपयोग करके ऐसे ऑपरेशन किए जाते हैं!

क्या +ऑपरेटर को एमओएसटी कार्यान्वयन पर पोस्ट किए गए कोड के रूप में लागू किया गया है? क्या यह दो पूरक या अन्य कार्यान्वयन-निर्भर सुविधाओं का लाभ उठाता है?


60
मुझे लगता है कि अधिकांश कार्यान्वयन देशी addमशीन अनुदेश का उपयोग करेंगे , जो मुझे लगता है कि सभी सीपीयू में हार्डवेयर योजक के रूप में लागू किया गया है और कुछ घड़ियों में काम करता है।
माइकैट

3
हां, +ऑपरेटर बहुत संभव है कि कार्यान्वयन परिभाषित सुविधाओं का लाभ उठाता है। इन्हें "मशीन भाषा" और "सीपीयू" कहा जाता है। आपका प्रश्न क्या है? यदि आप जानना चाहते हैं कि कैसे भावों को मशीन कोड में बदला जाता है, तो कृपया संकलक निर्माण के बारे में पढ़ें।
इस साइट के लिए बहुत ही ईमानदार

क्या आपको लगता है कि मेरे द्वारा पोस्ट किया गया कोड पूरी तरह से बेकार है, क्योंकि कंपाइलर द्वारा +असेंबली निर्देशों का अनुवाद किया जाता addहै?
नलजोक

11
अधिकांश +कार्यों को मशीन कोड निर्देशों के कुछ प्रकार (या संयोजन) में संकलित किया जाएगा add। आपका कोड हर वास्तविक दुनिया के परिदृश्य में जटिल और बेकार है, लेकिन यह द्विआधारी संचालन के बारे में सिखाने के लिए काम कर सकता है
एंडर्स तोर्ब्लाद

11
जबकि C यह कैसे नहीं करता है (नीचे दिए गए उत्तर देखें), यह काफी करीब है कि इसमें शामिल सर्किटरी सबसे निचले स्तर पर कैसे जुड़ सकती है। छोटे बाइनरी मान (3- या 4-बिट बाइट्स) के लिए कागज और कलम में इसके माध्यम से काम करने की कोशिश करें और देखें कि यह कैसे काम करता है। अब कल्पना करें कि कैसे सर्किटरी विद्युत दालों के साथ एक ही काम कर सकता था। अब एक लूप के बजाय सभी बिट्स को समानांतर में करने की कल्पना करें। अब आप 1940 के युग का कंप्यूटर बनाने के लिए तैयार हैं: D
जॉन हैना

जवाबों:


184

पांडित्यपूर्ण होने के लिए, सी विनिर्देश निर्दिष्ट नहीं करता है कि कैसे लागू किया जाता है।

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

सीपीयू आंतरिक रूप से जोड़ को लागू करने के लिए तर्क सर्किट का उपयोग करता है, और छोरों, बिटशिफ्ट्स या ऐसी किसी भी चीज का उपयोग नहीं करता है, जो सी काम करने के लिए एक करीबी समानता है।


12
यह उत्तर उत्कृष्ट है क्योंकि यह असामान्य स्पष्टता और सरलता के साथ प्रस्तुत किया गया है। मुझे यह बिल्कुल पांडित्यपूर्ण नहीं लगता, सवाल के लिए केवल पैन्शेंट्री की सही खुराक।
जेरेमी एंडरसन

5
@orlp वास्तव में, सीपीयू लॉजिक सर्किट को एचडीएल से संकलित किया जा सकता है, और आप ओपी के सुझाव (लेकिन केवल अस्पष्ट) के समान लूप्स और बिटशफ्ट्स का उपयोग करके एक योजक उत्पन्न करने की संभावना रखते हैं। कहा छोरों और बिटशिफ्ट्स हार्डवेयर के लेआउट का वर्णन करते हैं और वे कैसे जुड़े हैं। फिर, टॉप-टियर हार्डवेयर में, किसी ने कहा कि लूप्स और बिटशिफ्ट्स को अनियंत्रित किया जा सकता है, या एचडीएल के साथ भी दूर किया जा सकता है और एक योजक के रूप में प्रदर्शन के लिए महत्वपूर्ण रूप से कुछ के लिए सर्किट को बाहर रखना चाहिए।
यक्क - एडम नेवरामोंट

5
एक रैखिक योजक सर्किट वास्तव में वही करता है जो C कोड करता है लेकिन लूप हार्डवेयर (32 बार) में पूरी तरह से अनियंत्रित होता है।
usr

2
@usr न सिर्फ अनियंत्रित होता है, बल्कि हर "स्टेप" एक साथ होता है।
ऑरेंजडॉग

4
@OrangeDog एक सरल हार्डवेयर योजक में बहुत सी कैरी रिपलिंग होगी जैसे यह C कोड करता है जो समानतावाद को सीमित करता है। उच्च प्रदर्शन योजक इसे कम करने के लिए कैरी लुकहेड सर्किट का उपयोग कर सकते हैं।
22

77

जब आप दो बिट्स जोड़ते हैं, तो परिणाम निम्न है: (सत्य तालिका)

इसलिए अगर आप बिटकॉइन एक्सर करते हैं, तो आपको बिना कैरी के ही रकम मिल सकती है। और अगर आप बिटवाइज़ करते हैं और आप कैरी बिट्स प्राप्त कर सकते हैं।

मल्टीबिट संख्या aऔर के लिए इस अवलोकन का विस्तारb

एक बार bहै 0:

तो एल्गोरिथ्म नीचे उबलता है:

यदि आप पुनरावृत्ति से छुटकारा पा लेते हैं और इसे एक लूप में बदल देते हैं


कोड से ऊपर मन में स्पष्टीकरण के साथ एल्गोरिथ्म सरल होना चाहिए:

बिट्स ले। दोनों ऑपरेंड में दाईं ओर 1 बिट 1 होने पर कैरी बिट 1 है।

कैरी के बिना जोड़ (कैरी बिट्स की अनदेखी)

इसे ले जाने के लिए x का पुन: उपयोग करें

अधिक कैरी बिट होने पर दोहराएं


एक पुनरावर्ती कार्यान्वयन (समझने में आसान) होगा:

लगता है कि यह फ़ंक्शन दर्शाता है कि पृष्ठभूमि में वास्तव में कैसे काम करता है

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


5
यह सबसे अच्छा उत्तर imo है, अन्य सभी राज्य बताते हैं कि यह आमतौर पर एक ही निर्देश के लिए अनुवादित है, लेकिन यह ऐसा करता है और दिए गए फ़ंक्शन को भी समझाता है।
निक स्वीटिंग

@NickSweeting धन्यवाद। प्रश्न की व्याख्या 2 तरीकों से की जा सकती है और मुझे लगता है कि स्वीकृत उत्तर ने यह व्याख्या की है कि ओपी क्या पूछना चाहता है।
मोहित जैन

25

लगता है कि यह फ़ंक्शन दर्शाता है कि पृष्ठभूमि में वास्तव में कैसे काम करता है

यह देशी addमशीन अनुदेश का अनुवाद है , जो वास्तव में हार्डवेयर योजक का उपयोग कर रहा है, में ALU

यदि आप सोच रहे हैं कि कंप्यूटर कैसे जोड़ता है, तो यहां एक बुनियादी योजक है।

कंप्यूटर में सब कुछ लॉजिक गेट्स का उपयोग करके किया जाता है, जो ज्यादातर ट्रांजिस्टर से बने होते हैं। पूर्ण योजक में अर्ध-योजक होते हैं।

लॉजिक गेट्स और ऐडर्स पर बेसिक ट्यूटोरियल के लिए इसे देखें । वीडियो बहुत उपयोगी है, हालांकि लंबा है।

उस वीडियो में, एक मूल आधा-योजक दिखाया गया है। यदि आप एक संक्षिप्त विवरण चाहते हैं, तो यह है:

आधा योजक जोड़ने के दो बिट दिए गए हैं। संभावित संयोजन हैं:

  • 0 और 0 = 0 जोड़ें
  • 1 और 0 = 1 जोड़ें
  • 1 और 1 = 10 (बाइनरी) जोड़ें

तो अब आधा योजक कैसे काम करता है? खैर, यह तीन तर्क द्वारों से बना है and, xorऔर nandnand एक सकारात्मक वर्तमान देता है अगर दोनों आदानों नकारात्मक हैं, ताकि साधन इस हल करती 0 और 0 के मामले xorइनपुट का एक सकारात्मक उत्पादन एक सकारात्मक है देता है, और अन्य नकारात्मक है, तो इसका मतलब है कि यह की समस्या का हल 1 और 0. andदोनों इनपुट सकारात्मक होने पर ही एक सकारात्मक आउटपुट देता है, जिससे 1 और 1 की समस्या हल हो जाती है। इसलिए मूल रूप से, हमें अब अपना आधा-योजक मिल गया है। लेकिन हम अभी भी केवल बिट्स जोड़ सकते हैं।

अब हम अपना पूर्ण-योजक बनाते हैं। एक पूर्ण योजक में बार-बार आधे योजक को कॉल करना शामिल है। अब यह एक कैरी है। जब हम 1 और 1 जोड़ते हैं, तो हमें एक कैरी मिलती है। 1. पूर्ण-योजक क्या करता है, यह आधे-योजक से कैरी लेता है, इसे संग्रहीत करता है, और इसे अर्ध-योजक के एक अन्य तर्क के रूप में पास करता है।

यदि आप भ्रमित हैं कि आप कैरी को कैसे पास कर सकते हैं, तो आप मूल रूप से पहले आधे-योजक का उपयोग करके बिट्स जोड़ते हैं, और फिर योग और कैरी जोड़ते हैं। तो अब आपने दो बिट्स के साथ कैरी जोड़ा है। इसलिए आप बार-बार ऐसा करते हैं, जब तक कि बिट्स को आपको जोड़ना नहीं पड़ता, तब तक आप अपना परिणाम प्राप्त कर सकते हैं।

आश्चर्य चकित? ऐसा वास्तव में होता है। यह एक लंबी प्रक्रिया की तरह दिखता है, लेकिन कंप्यूटर इसे एक नैनोसेकंड के अंशों में, या आधे घंटे के चक्र में अधिक विशिष्ट होने के लिए करता है। कभी-कभी यह एकल घड़ी चक्र में भी किया जाता है। मूल रूप से, कंप्यूटर में ALU() का एक प्रमुख हिस्सा CPU, मेमोरी, बसें आदि हैं।

यदि आप लॉजिक गेट, मेमोरी और ALU से कंप्यूटर हार्डवेयर सीखना चाहते हैं, और कंप्यूटर का अनुकरण करते हैं, तो आप इस कोर्स को देख सकते हैं, जहाँ से मैंने यह सब सीखा है: पहले सिद्धांतों से एक आधुनिक कंप्यूटर बनाएँ

यदि आप ई-प्रमाणपत्र नहीं चाहते हैं तो यह मुफ़्त है। पाठ्यक्रम के भाग दो इस साल वसंत में आ रहे हैं


11
कुछ मिलीसेकंड? एकल ऐड के लिए?
JAB

2
आम तौर पर दो अपंजीकृत मूल्यों के साथ जोड़ एक ही घड़ी में पूरा होता है।
कोड़ी ग्रे

5
@ तमोग्ना चौधरी: एक नैनोसेकंड के कुछ अंशों को आज़माएं। रजिस्टर ऐड हाल के इंटेल प्रोसेसर पर आईआईआरसी एक घड़ी है, इसलिए कई गीगाहर्ट्ज की घड़ी की गति के साथ ... और यह पाइपलाइनिंग, सुपरस्क्लेयर निष्पादन और इस तरह की गिनती नहीं है।
18

यह रिपल-कैरी योजक बहुत विलंबता जोड़ देगा, इसलिए इसे हार्डवेयर में भी इस तरह से लागू नहीं किया गया है।
पाइप

Ripple-carry योजक CPU द्वारा दशकों से उपयोग नहीं किया गया है, क्योंकि यह बहुत धीमा है। इसके बजाय, वे अधिक जटिल योजक का उपयोग करते हैं जो इंटेल के कुछ डबल-क्लॉक किए गए ALU के मामले में एकल घड़ी चक्र (या यहां तक ​​कि आधा चक्र) में काम कर सकते हैं। (खैर, अधिकांश सीपीयू इसका उपयोग नहीं करते हैं। निम्न-अंत एम्बेडेड सीपीयू अभी भी इसे कम ट्रांजिस्टर गणना के लिए उपयोग कर सकते हैं।)
मार्क

15

C कोड क्या करता है, यह बताने के लिए C एक अमूर्त मशीन का उपयोग करता है। तो यह कैसे काम करता है निर्दिष्ट नहीं है। सी "कंपाइलर" हैं जो वास्तव में सी को स्क्रिप्टिंग भाषा में संकलित करते हैं, उदाहरण के लिए।

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

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

अंकगणितीय तर्क इकाई में अलग-अलग योजक और गुणक हो सकते हैं, या उन्हें एक साथ मिला सकते हैं।

अंकगणित तर्क इकाई में ट्रांजिस्टर का एक गुच्छा होता है जो अतिरिक्त संचालन करता है, फिर आउटपुट का उत्पादन करता है। कहा आउटपुट निर्देश डिकोडर से उत्पन्न संकेतों के माध्यम से चलाया जाता है, और मेमोरी या रजिस्टरों में संग्रहीत किया जाता है।

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

हार्डवेयर विवरण भाषा में बदलाव और लूप शामिल हो सकते हैं जो समय में होने वाली चीजों (जैसे एक के बाद एक) का वर्णन नहीं करते हैं , बल्कि अंतरिक्ष में - यह हार्डवेयर के विभिन्न भागों के बीच कनेक्शन का वर्णन करता है। कहा गया कोड आपके द्वारा ऊपर पोस्ट किए गए कोड की तरह बहुत अस्पष्ट लग सकता है।

उपरोक्त कई हिस्सों और परतों पर चमकता है और इसमें अशुद्धियाँ होती हैं। यह मेरी स्वयं की अक्षमता से है (मैंने हार्डवेयर और संकलक दोनों को लिखा है, लेकिन दोनों में से कोई भी विशेषज्ञ नहीं हूं) और क्योंकि पूर्ण विवरण कैरियर या दो ले जाएगा, और एसओ पद नहीं।

यहाँ 8-बिट योजक के बारे में एक SO पोस्ट है। यहां एक गैर-एसओ पोस्ट है, जहां आप operator+एचडीएल में उपयोग किए जाने वाले कुछ योजक को नोट करेंगे ! (एचडीएल खुद ही आपके +लिए निचले स्तर के योजक कोड को समझता है और उत्पन्न करता है)।


14

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

आपके द्वारा पोस्ट किया गया कोड इस अवलोकन पर निर्भर करता है कि x और y को जोड़ते समय, आप इसे उन बिट्स में समाप्‍त कर सकते हैं जो उनके पास समान हैं और बिट्स जो x या y में से किसी एक के लिए अद्वितीय हैं।

एक्सप्रेशन x & y(बिट वाइज) बिट्स को x और y को सामान्य देता है। एक्सप्रेशन x ^ y(बिटवाइज़ एक्सक्लूसिव OR) उन बिट्स को देता है जो एक्स या वाई में से एक के लिए अद्वितीय हैं।

इस राशि x + yको दो गुना बिट्स के योग के रूप में फिर से लिखा जा सकता है (क्योंकि x और y दोनों उन बिट्स में योगदान करते हैं) प्लस बिट्स जो x या y के लिए अद्वितीय हैं।

(x & y) << 1 सामान्य रूप से उनके पास दो बार बिट्स हैं (बाईं ओर 1 से प्रभावी रूप से दो गुणा गुणा)।

x ^ y बिट्स जो x या y में से एक के लिए अद्वितीय हैं।

इसलिए यदि हम x को पहले मान से और y को दूसरे द्वारा प्रतिस्थापित करते हैं, तो योग अपरिवर्तित होना चाहिए। आप पहले मूल्य को बिटवाइस परिवर्धन के वहन के रूप में और दूसरे को बिटकॉइन परिवर्धन के निम्न-क्रम बिट के रूप में सोच सकते हैं।

यह प्रक्रिया तब तक जारी रहती है जब तक कि x शून्य नहीं होता, जिस बिंदु पर y का योग होता है।


14

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

सामान्य जीवन में, आप दशमलव संख्याओं का उपयोग करते हैं और आपने उन्हें जोड़ना सीख लिया है: दो संख्याएँ जोड़ने के लिए, आप सबसे कम दो अंकों को जोड़ते हैं। यदि परिणाम 10 से कम है, तो आप परिणाम लिखते हैं और अगले अंक की स्थिति में आगे बढ़ते हैं। यदि परिणाम 10 या अधिक है, तो आप परिणाम माइनस 10 लिखते हैं, अगले अंक पर आगे बढ़ें, आपको 1 और जोड़ने के लिए याद रखें। उदाहरण के लिए: 23 + 37, आप 3 + 7 = 10 जोड़ते हैं, आप 0 लिखते हैं और अगली स्थिति के लिए 1 और जोड़ना याद करते हैं। 10 वें स्थान पर, आप (2 + 3) + 1 = 6 जोड़ते हैं और इसे लिखते हैं। परिणाम 60 है।

आप बाइनरी नंबर के साथ सटीक एक ही काम कर सकते हैं। अंतर यह है कि केवल अंक 0 और 1 हैं, इसलिए एकमात्र संभव योग 0, 1, 2 हैं। 32 बिट संख्या के लिए, आप एक के बाद एक अंकों की स्थिति को संभाल लेंगे। और यह है कि वास्तव में आदिम कंप्यूटर हार्डवेयर यह कैसे करेगा।

यह कोड अलग तरह से काम करता है। आप जानते हैं कि दो द्विआधारी अंकों का योग 2 है यदि दोनों अंक 1. हैं, तो यदि दोनों अंक 1 हैं, तो आप अगले द्विआधारी स्थिति में 1 और जोड़ेंगे और नीचे लिखेंगे 0. यही टी की गणना है: यह सभी स्थानों को ढूंढता है जहाँ दोनों बाइनरी अंक 1 हैं (यह &) है और उन्हें अगले अंक की स्थिति (<< 1) पर ले जाता है। फिर यह जोड़ करता है: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, 1 + 1 2 है, लेकिन हम नीचे लिखते हैं 0. यह है कि बहिष्कृत या ऑपरेटर क्या करता है।

लेकिन सभी 1 है कि आप अगले अंक की स्थिति में संभाल करने के लिए संभाल नहीं किया गया है। उन्हें अभी भी जोड़े जाने की आवश्यकता है। इसलिए कोड एक लूप करता है: अगली पुनरावृत्ति में, सभी अतिरिक्त 1 जोड़े जाते हैं।

कोई प्रोसेसर ऐसा क्यों नहीं करता है? क्योंकि यह एक लूप है, और प्रोसेसर को लूप पसंद नहीं है, और यह धीमा है। यह धीमा है, क्योंकि सबसे खराब स्थिति में, 32 पुनरावृत्तियों की आवश्यकता होती है: यदि आप 1 को 0xffffffff (32 1-बिट्स) में जोड़ते हैं, तो पहला पुनरावृत्ति y का बिट 0 सेट करता है और x को 2 पर सेट करता है। दूसरा पुनरावृत्ति बिट्स 1 y और सेट x से 4. और इसी तरह। परिणाम प्राप्त करने के लिए 32 पुनरावृत्तियों लगते हैं। हालाँकि, प्रत्येक पुनरावृत्ति को x और y के सभी बिट्स को संसाधित करना पड़ता है, जो बहुत सारे हार्डवेयर लेता है।

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

एक आधुनिक, तेज और जटिल सीपीयू "सशर्त योग योजक" का उपयोग करेगा। विशेष रूप से यदि बिट्स की संख्या अधिक है, उदाहरण के लिए, 64 बिट योजक, यह बहुत समय बचाता है।

64 बिट योजक में दो भाग होते हैं: पहला, सबसे कम 32 बिट के लिए एक 32 बिट योजक। वह 32 बिट योजक एक योग उत्पन्न करता है, और एक "कैरी" (एक संकेतक जो 1 को अगले बिट स्थिति में जोड़ा जाना चाहिए)। दूसरा, उच्च 32 बिट्स के लिए दो 32 बिट योजक: एक x + y जोड़ता है, दूसरा x + y + 1. जोड़ता है, सभी तीन योजक समानांतर में काम करते हैं। फिर जब पहले योजक ने अपने कैरी का उत्पादन किया है, तो सीपीयू सिर्फ चुनता है जो दो परिणामों में से एक x + y या x + y + 1 सही है, और आपके पास पूरा परिणाम है। तो एक 64 बिट योजक केवल 32 बिट योजक की तुलना में एक छोटा सा अधिक समय लेता है, न कि दो बार।

32 बिट योजक भागों को फिर से सशर्त योग योजक के रूप में लागू किया जाता है, कई 16 बिट योजक का उपयोग करते हुए, और 16 बिट योजक सशर्त योग योजक होते हैं, और इसी तरह।


13

मेरा प्रश्न है: क्या MOST कार्यान्वयन पर पोस्ट किए गए कोड के रूप में + ऑपरेटर को लागू किया गया है?

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

कंपाइलर किसी भी कोड को उत्पन्न करने के लिए स्वतंत्र है जब तक यह व्यवहार करता है जैसे कि मानक के अनुसार वास्तविक संचालन किया गया था। लेकिन वास्तव में जो होता है वह कुछ पूरी तरह से अलग हो सकता है।

एक सरल उदाहरण:

यहां कोई अतिरिक्त निर्देश उत्पन्न करने की आवश्यकता नहीं है। यह संकलक के लिए यह पूरी तरह से कानूनी है:

या हो सकता है कि संकलक ने नोटिस किया कि आप फ़ंक्शन fooको एक पंक्ति में कुछ बार कहते हैं और यह एक साधारण अंकगणित है और यह इसके लिए वेक्टर निर्देश उत्पन्न करेगा। या इसके अलावा जोड़ के परिणाम का उपयोग बाद में सरणी अनुक्रमण के लिए किया जाता है और leaअनुदेश का उपयोग किया जाएगा।

आप बस इस बारे में बात नहीं कर सकते हैं कि एक ऑपरेटर को कैसे लागू किया जाता है क्योंकि यह लगभग कभी भी अकेले उपयोग नहीं किया जाता है।


11

यदि कोड का टूटना किसी और की मदद करता है, तो उदाहरण लें x=2, y=6:


xशून्य नहीं है, इसलिए इसमें जोड़ना शुरू करें y:

x & y = 2 चूंकि

2 <<1 = 4क्योंकि << 1सभी बिट्स बाईं ओर शिफ्ट होती हैं:

संक्षेप में, उस परिणाम को, साथ 4में , मिटा देंt

अब बिटवाइज़ XOR लागू करें y^=x:

तो x=2, y=4। अंत में, t+yरीसेट x=tऔर whileलूप की शुरुआत में वापस जाने के योग :

जब t=0(या, लूप की शुरुआत में x=0), के साथ समाप्त करें


1
हम पहले ही इस बात की अच्छी व्याख्या कर चुके थे कि हम कैरी बिट को क्यों रोकते हैं, इसलिए मैं यह जवाब देता हूं कि यह दिखाने के लिए कि कोड कैसे काम कर रहा है।
user1717828

11

बस ब्याज से बाहर, Atmega328P प्रोसेसर पर, avr-g ++ संकलक के साथ, निम्नलिखित कोड -1 घटाकर एक को जोड़ देता है:

volatile char x;
int main ()
  {
  x = x + 1;  
  }

उत्पन्न कोड:

00000090 <main>:
volatile char x;
int main ()
  {
  x = x + 1;  
  90:   80 91 00 01     lds r24, 0x0100
  94:   8f 5f           subi    r24, 0xFF   ; 255
  96:   80 93 00 01     sts 0x0100, r24
  }
  9a:   80 e0           ldi r24, 0x00   ; 0
  9c:   90 e0           ldi r25, 0x00   ; 0
  9e:   08 95           ret

विशेष रूप से ध्यान दें कि ऐड subiनिर्देश द्वारा किया जाता है (रजिस्टर से निरंतर घटाना) जहां 0xFF प्रभावी रूप से इस मामले में -1 है।

इसके अलावा रुचि यह है कि इस विशेष प्रोसेसर में एक addiनिर्देश नहीं है , जिसका अर्थ है कि डिजाइनरों ने सोचा था कि पूरक के घटाव को संकलक-लेखकों द्वारा पर्याप्त रूप से नियंत्रित किया जाएगा।

क्या यह दो पूरक या अन्य कार्यान्वयन-निर्भर सुविधाओं का लाभ उठाता है?

यह कहना शायद उचित होगा कि संकलक-लेखक उस विशेष रूप से वास्तुकला के लिए संभवतया सबसे कुशल तरीके से वांछित प्रभाव (एक संख्या को दूसरे में जोड़ना) को लागू करने का प्रयास करेंगे। यदि उस पूरक को घटाना आवश्यक है, तो यह हो।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.