एक माइक्रोप्रोसेसर में ALU एक हस्ताक्षरित संख्या के बीच अंतर कैसे करेगा, -7 जो कि 1111 द्वारा निरूपित है और एक अहस्ताक्षरित संख्या 15, जिसे 1111 भी निरूपित किया गया है?
एक माइक्रोप्रोसेसर में ALU एक हस्ताक्षरित संख्या के बीच अंतर कैसे करेगा, -7 जो कि 1111 द्वारा निरूपित है और एक अहस्ताक्षरित संख्या 15, जिसे 1111 भी निरूपित किया गया है?
जवाबों:
संक्षिप्त और सरल उत्तर है: यह नहीं है। कोई भी आधुनिक मुख्यधारा CPU ISA आपके सोचने के तरीके को काम नहीं करता है।
सीपीयू के लिए, यह सिर्फ एक बिट पैटर्न है। यह आप पर निर्भर है, प्रोग्रामर, उस बिट पैटर्न का क्या अर्थ है, इसका ट्रैक रखता है।
सामान्य तौर पर, ISAs विभिन्न डेटा प्रकारों के बीच अंतर नहीं करते हैं, जब यह भंडारण की बात आती है। (एफपीयू में फ्लोटिंग रजिस्टरों जैसे विशेष प्रयोजन के रजिस्टरों को अनदेखा करना।) यह सीपीयू के लिए बिट्स का सिर्फ एक अर्थहीन पैटर्न है। हालांकि, ISAs कर निर्देश है कि अलग अलग तरीकों से थोड़ा पैटर्न व्याख्या कर सकते हैं के विभिन्न प्रकार की है। उदाहरण के लिए, गणित निर्देश जैसे MUL
, DIV
, ADD
, SUB
संख्या के कुछ प्रकार के रूप में बिट पैटर्न, की व्याख्या इस तरह के रूप तार्किक निर्देश जबकि AND
, OR
, XOR
बूलियन्स की एक सरणी के रूप में यह व्याख्या। तो, यह सही प्रोग्रामर चुनने के लिए प्रोग्रामर, (या दुभाषिया या संकलक के लेखक का उपयोग करता है)।
उदाहरण के लिए, हस्ताक्षरित बनाम अहस्ताक्षरित संख्याओं के लिए अलग-अलग निर्देश हो सकते हैं। कुछ ISAs के पास द्विआधारी-कोडित दशमलव के साथ अंकगणित के लिए निर्देश भी हैं।
हालांकि, ध्यान दें कि मैंने ऊपर "आधुनिक मुख्यधारा आईएसए" लिखा था। वास्तव में गैर-मुख्यधारा या ऐतिहासिक आईएसए हैं जो अलग तरीके से काम करते हैं। उदाहरण के लिए, IBM AS / 400 के मूल 48-बिट CISC ISA के साथ-साथ वर्तमान पावर-आधारित 64-बिट RISC ISA सिस्टम जिसे अब IBM i कहा जाता है, पॉइंटर्स और अन्य मानों के बीच अंतर करता है। पॉइंटर्स को हमेशा टैग किया जाता है, और उनमें टाइप इंफॉर्मेशन और राइट्स मैनेजमेंट शामिल होता है। सीपीयू जानता है कि क्या कोई मान सूचक है या नहीं, और केवल विशेषाधिकार प्राप्त i / OS कर्नेल को स्वतंत्र रूप से पॉइंटर्स में हेरफेर करने की अनुमति है। उपयोगकर्ता अनुप्रयोग केवल उन बिंदुओं में हेरफेर कर सकते हैं जो वे स्मृति में इंगित करने के लिए सुरक्षित निर्देशों का एक छोटी संख्या का उपयोग करते हैं।
कुछ ऐतिहासिक ISA डिजाइन भी थे जिनमें कम से कम कुछ सीमित प्रकार के जागरूकता शामिल थे।
char
जो एक 16-बिट अहस्ताक्षरित प्रकार है,। बेशक, जावा बाइटकोड में अभी भी कोई अहस्ताक्षरित अंकगणितीय निर्देश नहीं हैं, क्योंकि अंकगणित के लिए किसी भी char
मान को स्वचालित रूप से int
(32-बिट हस्ताक्षरित) प्रचारित किया जाता है ।
लघु संस्करण: यह नहीं पता। बताने का कोई उपाय नहीं है।
यदि 1111
-7 का प्रतिनिधित्व करता है, तो आपके पास एक संकेत-परिमाण प्रतिनिधित्व है , जहां पहला बिट संकेत है और शेष बिट्स परिमाण हैं। इस मामले में, अंकगणित कुछ जटिल है, क्योंकि एक अहस्ताक्षरित ऐड और एक हस्ताक्षरित ऐड विभिन्न तर्क का उपयोग करते हैं। तो आपके पास शायद एक SADD
और एक UADD
opcode होगा, और यदि आप गलत का चयन करते हैं तो आपको निरर्थक परिणाम मिलते हैं।
अधिक बार, हालांकि, 1111
-1 का प्रतिनिधित्व करता है, जिसे दो-पूरक प्रतिनिधित्व कहा जाता है । इस मामले में, ALU बस परवाह नहीं करता है अगर संख्याएं हस्ताक्षरित हैं या अहस्ताक्षरित हैं! उदाहरण के लिए, चलिए ऑपरेशन करते हैं 1110 + 0001
। हस्ताक्षरित अंकगणित में, इसका अर्थ है "-2 + 1", और परिणाम -1 ( 1111
) होना चाहिए । अहस्ताक्षरित अंकगणित में, इसका अर्थ "14 + 1" है, और परिणाम 15 ( 1111
) होना चाहिए । इसलिए ALU नहीं जानता कि आप एक हस्ताक्षरित या अहस्ताक्षरित परिणाम चाहते हैं, और यह परवाह नहीं करता है। यह सिर्फ इसके अलावा करता है जैसे कि यह अहस्ताक्षरित था, और यदि आप उस पर हस्ताक्षर किए गए पूर्णांक के रूप में इलाज करना चाहते हैं, तो यह आपके ऊपर है।
EDIT: जैसा कि रुस्लान और डैनियल शेप्लेर ने टिप्पणी में काफी हद तक सही बताया है, कुछ ऑपरेंड्स को अभी भी अलग-अलग हस्ताक्षरित और अहस्ताक्षरित संस्करणों की आवश्यकता है, यहां तक कि दो-पूरक मशीन पर भी। जोड़, घटाव, गुणा, समानता और इस तरह के सभी यह जानने के बिना ठीक काम करते हैं कि संख्याएँ हस्ताक्षरित हैं या नहीं। लेकिन विभाजन और किसी भी तुलना में अधिक / कम-तुलना की तुलना में अलग संस्करण हैं।
EDIT EDIT: कुछ अन्य अभ्यावेदन भी हैं, जैसे एक -पूरक , लेकिन ये मूल रूप से कभी भी उपयोग नहीं किए जाते हैं इसलिए आपको इनके बारे में चिंता नहीं करनी चाहिए।
<
<=
>=
>
विभिन्न बनाम जबकि अहस्ताक्षरित ऑपरेंड पर हस्ताक्षर किए के लिए कर रहे हैं ==
और !=
signedness-नास्तिक हैं।
दो-पूरक गणित के महान लाभों में से एक, जो सभी आधुनिक आर्किटेक्चर उपयोग करते हैं, यह है कि अतिरिक्त और घटाव निर्देश हस्ताक्षरित और अहस्ताक्षरित दोनों ऑपरेंड के लिए बिल्कुल समान हैं।
कई सीपीयू में गुणा, विभाजन या मापांक निर्देश भी नहीं होते हैं। यदि वे करते हैं, तो उनके पास निर्देश के अलग-अलग हस्ताक्षरित और अहस्ताक्षरित रूप होने चाहिए, और संकलक (या असेंबली-भाषा प्रोग्रामर) उपयुक्त चुनता है।
सीपीयू में आम तौर पर हस्ताक्षरित या अहस्ताक्षरित तुलना के लिए अलग-अलग निर्देश होते हैं। उदाहरण के लिए, यदि तुलना की जानी चाहिए , तो x86 एक के CMP
साथ अनुसरण कर सकता है JL
(यदि इससे कम है तो कूदें), यदि तुलना पर हस्ताक्षर किए जाने चाहिए या JB
(नीचे नीचे कूदें)। फिर से, कंपाइलर या प्रोग्रामर डेटा प्रकार के लिए सही निर्देश का चयन करेगा।
कुछ अन्य निर्देश अक्सर हस्ताक्षरित और अहस्ताक्षरित वेरिएंट में आते हैं, जैसे कि सही बदलाव या एक व्यापक रजिस्टर में मूल्य को लोड करना, साइन-एक्सटेंशन के साथ या बिना।
smulh
और umulh
गुणा के केवल ऊपरी बिट्स पर हस्ताक्षर करते हैं और उन निर्देशों को अनसुना करते हैं स्रोत ऑपरेंड के रूप में दो बार एक रजिस्टर में परिणाम लौटाएं।
यह नहीं है प्रोसेसर यह निर्देश सेट पर निर्भर करता है कि वह यह बताए कि वह किस प्रकार का डेटा देख रहा है और उसे कहां भेजना है। ऑपरेंड में ही 1s और 0s के बारे में कुछ भी नहीं है जो स्वाभाविक रूप से ALU को संकेत दे सकता है कि क्या डेटा एक चार, फ्लोट, इंट, हस्ताक्षरित इंट, आदि है। यदि 1111 एक इलेक्ट्रिक सर्किट में जा रहा है जो 2s के पूरक की उम्मीद कर रहा है, तो यह चल रहा है। एक 2s पूरक के रूप में व्याख्या की जाए।
char
हार्डवेयर स्तर पर ऐसी कोई बात नहीं है। हो सकता है कि एक बार यांत्रिक टेलीप्रिंटर्स के दिनों में वापस। लेकिन आज, एक char
है सिर्फ एक संख्या के रूप में दूर के रूप में हार्डवेयर का संबंध है। अलग-अलग संख्याएँ आपकी स्क्रीन पर अलग-अलग अक्षर आकृतियों के अनुरूप होती हैं, इसका कारण यह है कि उन संख्याओं का उपयोग अलग-अलग बिटमैप या किसी बड़ी तालिका (यानी, "फ़ॉन्ट" से) के अलग-अलग ड्राइंग रूटीनों को चुनने के लिए किया जाता है।
मैं पहले से किए गए उत्तरों को जोड़ देना चाहता हूं:
अधिकांश अन्य उत्तरों में यह ध्यान दिया जाता है कि दो-पूरक अंकगणित में परिणाम हस्ताक्षरित और अहस्ताक्षरित संख्याओं के लिए समान है:
-2 + 1 = -1 1110 + 0001 = 1111
14 + 1 = 15 1110 + 0001 = 1111
हालाँकि , इसके कुछ अपवाद भी हैं:
Division:
-2 / 2 = -1 1110 / 0010 = 1111
14 / 2 = 7 1110 / 0010 = 0111
Comparison:
-2 < 2 = TRUE 1110 < 0010 = TRUE
14 < 2 = FALSE 1110 < 0010 = FALSE
"Typical" (*) multiplication:
-2 * 2 = -4 1110 * 0010 = 11111100
14 * 2 = 28 1110 * 0010 = 00011100
(*) कई सीपीयू पर दो n-बिट संख्याओं के गुणन का परिणाम (2 * n) बिट्स चौड़ा होता है।
ऐसे कार्यों के लिए सीपीयू के पास हस्ताक्षरित और अहस्ताक्षरित अंकगणित के लिए अलग-अलग निर्देश हैं।
इसका मतलब है कि प्रोग्रामर (या संकलक) को हस्ताक्षरित और अहस्ताक्षरित अंकगणित के लिए अन्य निर्देशों का उपयोग करना चाहिए।
उदाहरण के लिए x86 CPU में div
एक अहस्ताक्षरित विभाजन idiv
करने के लिए एक निर्देश है और एक हस्ताक्षरित विभाजन करने के लिए एक निर्देश है ।
अलग-अलग "सशर्त" निर्देश (सशर्त छलांग, सेट-बिट-ऑन-कंडीशन) के साथ-साथ हस्ताक्षरित और अहस्ताक्षरित अंकगणित के लिए गुणन निर्देश भी हैं।