दोहरी पूर्णांक परिशुद्धता का सिर्फ एक विशेष मामला है मनमानी परिशुद्धता । असेंबली लैंग्वेज के स्तर पर इसे कैसे लागू किया जाता है यह ISA पर निर्भर है। (भले ही आपने विशेष रूप से x86 के बारे में पूछा हो, मैं कुछ अतिरिक्त जानकारी प्रदान करूंगा।)
इसके अलावा और घटाव के लिए, कई आईएसएएस (जैसे, एआरएम, पावर, x86) कैरी (घटाव के लिए उधार) प्रदान करते हैं और उधार निर्देशों के साथ ले जाने और घटाने के साथ विशेष जोड़ होते हैं।
ADD r1, r2, r3; // r1 = r2 + r3, set or clear carry bit
ADDC r4, r5, r6; // r4 = r5 + r6 + carry bit (also sets/clears carry)
कुछ ISAs (जैसे, अल्फा [जो हमेशा 64-बिट था], MIPS) एक कैरी बिट और विशेष ऐड / घटाना निर्देश प्रदान नहीं करते हैं। ये सेट-ऑन-कम-से-निर्देश का उपयोग कर सकते हैं (रजिस्टर को शून्य से कम और एक से कम और एक से कम होने पर) का परीक्षण करने के लिए कि क्या यह परिणाम किसी ऑपरेंड से कम है (जो निर्धारित करता है कि परिणाम एक कैरी उत्पन्न हुआ या नहीं) )।
ADD r1, r2, r3; // r1 = r2 + r3
ADD r4, r5, r6; // r4 = r5 + r6
SLT r7, r1, r2; // r7 = (r1 < r2)? 1 : 0 (determining carry)
ADD r4, r4, r7; // r4 = r4 + r7 (adding in carry)
(ISA डिज़ाइनर जिन्होंने कैरी बिट प्रदान करने के लिए नहीं चुना, ऐसा इसलिए किया गया क्योंकि कई सटीक ऑपरेशन कॉमन नहीं हैं, सिंगल कैरी बिट एक डेटा निर्भरता का परिचय देता है जो सुपरस्क्लेर ऑपरेशन में बाधा उत्पन्न करता है, और विशेष बिट्स आउट-ऑफ-ऑर्डर निष्पादन के लिए रजिस्टर का नाम बदलकर अधिक जटिल बनाते हैं ।)
गुणन के लिए, परिष्कृत एल्गोरिदम को अधिक कुशल बनाने के लिए दोगुनी सटीकता पर्याप्त नहीं हो सकती है, इसलिए आंशिक उत्पादों को बनाने और परिणामों को समेटने की सीधी विधि को प्राथमिकता दी जा सकती है। यह सूत्र का उपयोग करता है (जहां ए और सी दोहरे परिशुद्धता के ऊपरी आधे हिस्से हैं):
(a + b) * (c + d) = a*c + a*d + b*c + b*d.
(सादगी के लिए, निम्नलिखित किसी भी अतिरिक्त अनदेखी के साथ एक दोगुना सटीक परिणाम मानता है। इसका मतलब है कि उत्पाद शब्द * सी पूरी तरह से अनदेखा किया गया है।)
एक ISA (जैसे, MIPS, x86) के लिए जो एक एकल से उच्च और निम्न दोनों परिणाम प्रदान करता है, ऑपरेशन यथोचित सीधा है। निम्नलिखित एक है असभ्य x86 के लिए सन्निकटन (मैं विवरण से परिचित नहीं हूं):
MUL r2:r0, r3, r7; // multiply a*d
MOV r1, r0; // preserve low result of a*d
MUL r2:r0, r5, r6; // multiply b*c
MOV [temp], R0; // preserve low result on stack at temp
MUL r2:r0, r5, r7; // multiply b*d
ADD r2, r1; // add high b*d and low b*c for part of
// higher result
ADD r2, [temp]; // add partial higher result and low a*d
// doubled precision product is now in r2:r0
ISA के लिए (जैसे, अल्फा) उच्च परिणाम के लिए अलग-अलग गुणा और निम्न परिणाम निर्देशों के लिए एकाधिक प्रदान करता है (गुणन स्वाभाविक रूप से एक दोगुना सटीक मूल्य पैदा करता है), यह ऑपरेशन कुछ इसी तरह है:
// a*c result is beyond doubled precision range
MULL r16, r1, r4; // low multiply result (a*d)
// high a*d result is beyond doubled precision range
MULL r17, r2, r3; // low multiply result (b*c)
// high b*c result is beyond doubled precision range
MULL r18, r2, r4; // low multiply result (b*d)
MULH r19, r2, r4; // high multiply result (b*d)
ADD r20, r19, r17; // sum high (b*d) and low (b*c)
// for part of higher result
ADD r20, r20, r16; // sum partial result and low (a*d)
// double precision result is in r20:r16
(कुछ आईएसएएस एक गुणा के उच्च परिणाम प्राप्त करने का एक साधन प्रदान नहीं करते हैं। ऐसे आईएसएएस के लिए, ऑपरेंड को आधे आकार की इकाइयों में विभाजित किया जा सकता है और एक चौगुनी सटीक गुणा किया जाता है, हालांकि संभवतः अधिक परिष्कृत एल्गोरिथ्म है। जोड़ने के निर्देश स्पष्ट रूप से जोड़ और गुणन के दो को बहु-जोड़ में विलय कर सकते हैं।)
उपरोक्त छद्म विधानसभा कोड मानता है कि अतिप्रवाह एक चिंता का विषय नहीं है (और प्रदर्शन के लिए अनुकूलित नहीं है)। एक वास्तविक कार्यान्वयन इस तरह से ठीक से काम करेगा।
ग्नू मल्टीपल प्रिसिजन अरिथमेटिक लाइब्रेरी , मनमाने ढंग से सटीक अंकगणित के लिए एक खुला स्रोत पुस्तकालय, एक वास्तविक दुनिया कार्यान्वयन का विवरण प्रदान करेगा।
पता स्थान सीमाएँ
कारण यह है कि एक 32-बिट प्रोसेसर (एक साधारण अर्थ में) केवल 4 GiB मेमोरी का उपयोग कर सकता है, यह 32-बिट पॉइंटर्स / एड्रेस का उपयोग करता है और बाइट एड्रेसिंग का उपयोग करता है (इसलिए 2) 32 पते उपलब्ध हैं)। परंपरागत रूप से, यहां तक कि आभासी मेमोरी सिस्टम के साथ, एक भौतिक पता स्थान का समर्थन (जिसमें मेमोरी-मैप्ड I / O पते शामिल हैं, वैसे) 4 GiB से बड़ा अनावश्यक माना जाता था। (4 GiB भौतिक पता स्थान 32-बिट पेज तालिका प्रविष्टियों के लिए भी सुविधाजनक है, 4 KiB पृष्ठों का उपयोग करते समय वैधता, अनुमतियाँ और अन्य मेटाडेटा को परिभाषित करने के लिए 10 बिट्स का उपयोग करने की अनुमति देता है। 64-बिट पृष्ठ तालिका प्रविष्टियों का उपयोग करना चाहते हैं। छोटे सिस्टम के लिए अतिरिक्त मेमोरी, और प्रारंभिक 32-बिट सिस्टम छोटे थे।)
32-बिट आईएसएएस के जीवन का विस्तार करने के लिए, कुछ आईएसएएस (जैसे, एआरएम, x86) ने भौतिक पता एक्सटेंशन जोड़ा, जो एक बड़े भौतिक पते की अनुमति देने के लिए 64-बिट पृष्ठ तालिका प्रविष्टि का उपयोग करता है। यह वर्कअराउंड अजीब है, विशेष रूप से ओएस के लिए (जो सभी भौतिक मेमोरी का प्रबंधन करना चाहिए)।
कुछ आईएसएएस (जैसे एचपी पीए-आरआईएससी) ने एक विभाजन प्रणाली प्रदान की, जिसने उपयोगकर्ता के स्तर के कार्यक्रमों को पते के शीर्ष पर विशेष उद्देश्य खंड रजिस्टरों को जोड़कर एक बड़ा पता स्थान की अनुमति दी। (पॉवर [पीसी] सेगमेंट का भी उपयोग करता है, लेकिन मानों को unprivileged [अर्थात, एप्लिकेशन] सॉफ़्टवेयर द्वारा संशोधित नहीं किया जा सकता है।]
(सिद्धांत रूप में, एक ISA कुछ 8-बिट प्रोसेसर की तरह मेमोरी एड्रेसिंग क्षमताओं का विस्तार करने के लिए एक रजिस्टर जोड़ी का उपयोग कर सकता है। हालांकि, उस बिंदु से 64-बिट आईएसए में जाने से आम तौर पर अधिक समझ में आता है।)