गणित करना

गणित करना

सभी गणनाएँ रजिस्टरों के बीच होती हैं। एक अंकगणितीय निर्देश पहले गंतव्य का नाम लेता है, उसके बाद वे दो स्रोत जिन्हें वह पढ़ता है: का अर्थ है dest = src1 + src2।

अंकगणितीय संक्रिया
t2, t0, t1←add
t0 = 7t1 = 5+t2 = 12

t2 में t0 और t1 जोड़ें।

बाईं ओर से आने वाली दो पंक्तियाँ t0 और t1 हैं, हमेशा उसी क्रम में। वे समान आकृति में प्रवेश करती हैं चाहे कोई भी संक्रिया चल रही हो: जोड़, घटाव, गुणा, भाग, या शेषफल। दो मान अंदर जाते हैं, एक संक्रिया होती है, और एक परिणाम दाईं ओर t2 में आता है। पहले t2 का नाम लेता है क्योंकि वहीं परिणाम आता है, जो उस एक क्रम-नियम से मेल खाता है जिसका इस पाठ में हर अंकगणितीय निर्देश पालन करता है।

जोड़ना और घटाना

दो रजिस्टरों में रखी संख्याओं को लेता है और उनका योग तीसरे में संग्रहीत करता है। घटाव के लिए वही करता है: की गणना t0 - t1 करता है। दोनों निर्देश केवल रजिस्टरों से पढ़ते हैं।

गणित पंजीकृत करें
add t2, t0, t1 # t2 = t0 + t1
sub t2, t0, t1 # t2 = t0 - t1

एक बात जानने योग्य है: एक रजिस्टर केवल 32 बिट रखता है, इसलिए एक सीमा है। यदि कोई परिणाम इतना बड़ा है कि वह समा न सके, तो कोई त्रुटि नहीं उठाई जाती। मान चुपचाप चारों ओर लपेट जाता है बहुत छोटी संख्याओं में और निष्पादन जारी रहता है। रोज़मर्रा के मान इस सीमा तक नहीं पहुँचेंगे, लेकिन इस सीमा के बारे में जानना उपयोगी है।

दूसरे रजिस्टर के स्थान पर एक निश्चित संख्या का उपयोग करने के लिए, अक्षर i जोड़ें, जो तत्काल के लिए खड़ा है: स्थिरांक 1 जोड़ता है। कोई subi नहीं है, इसलिए एक स्थिरांक घटाने के लिए आप एक ऋणात्मक जोड़ें: ।

💡
एक स्थिरांक जोड़ता है। दो रजिस्टर जोड़ता है। इन दोनों को भ्रमित करना सबसे आम शुरुआती त्रुटि है।

गुणन और भाग

दो रजिस्टरों को गुणा करता है। उन्हें पूर्ण संख्याओं के रूप में विभाजित करता है और भिन्न को छोड़ देता है, इसलिए 7 / 2 का परिणाम 3 होता है। शेषफल देता है, इसलिए 7 % 2 का परिणाम 1 होता है। भाग कभी क्रैश नहीं करता। शून्य से भाग देने पर -1 लौटाता है।

गुणन, भाग, शेषफल
mul t2, t0, t1 # t2 = t0 * t1
div t2, t0, t1 # t2 = t0 / t1 (पूर्णांक)
rem t2, t0, t1 # t2 = t0 % t1 (शेषफल)

इसे एक साथ रखना

दो संख्याएँ जोड़ें और प्रिंट करें
li t0, 7
li t1, 5
add t1, t0, t1 # t1 = 7 + 5 = 12
mv a0, t1 # प्रिंट सेवा a0 पढ़ती है
li a7, 1
ecall
li a7, 10
ecall

t0 में 7 लोड करता है। t1 में 5 लोड करता है। उन्हें जोड़ता है और t1 में 12 लिखता है। परिणाम को a0 में प्रतिलिपित करता है, क्योंकि प्रिंट सेवा हमेशा अपना मान a0 से पढ़ती है। फिर प्रिंट-इंटीजर सेवा चुनता है और उसे चलाता है। अंत में, और प्रोग्राम समाप्त करते हैं।

बोनस: सरकाकर गुणा करना

जब गुणनखंड दो की घात हो, तो से तेज़ एक विधि मौजूद है। (शिफ्ट लेफ्ट लॉजिकल) एक रजिस्टर के बिट्स को बाईं ओर ले जाता है, और हर स्थान जितना आप शिफ्ट करते हैं मान को दोगुना करता है: 2 से गुणा करने के लिए 1 से शिफ्ट करें, 4 के लिए 2 से, 8 के लिए 3 से। शिफ्ट करना गुणा करने से कम खर्चीला है, इसलिए कंपाइलर इसे अक्सर उपयोग करते हैं।

शिफ्ट्स का उपयोग करके 8 से गुणा करें
li t0, 5 # 5 से शुरू करें
# 3 बिट बाईं ओर शिफ्ट करें (5 * 2^3 = 5 * 8)
sll a0, t0, 3 # a0 = 40
li a7, 1 # पूर्णांक प्रिंट करें
ecall
li a7, 10
ecall

t0 में 5 डालता है। इसके बिट्स को तीन स्थान बाईं ओर शिफ्ट करता है। हर स्थान मान को दोगुना करता है, इसलिए 5 तीन बार दोगुना होता है (5, 10, 20, 40), जिससे a0 में 40 आता है। शेष पहले वाले प्रिंट पैटर्न का पालन करता है। 3 को 1 या 2 में बदलकर देखें और चलाने से पहले परिणाम का अनुमान लगाएँ।

शिफ्ट करके गुणा करें
5sll a0, t0, 0
×2 →
10sll a0, t0, 1
×2 →
20sll a0, t0, 2
×2 →
40sll a0, t0, 3
0
0
0
0
0
1
0
1

5 को 0 बिट बाईं ओर शिफ्ट करने पर 5 ही रहता है।

आठ बॉक्स उनके ऊपर की संख्या का द्विआधारी रूप हैं, प्रत्येक एक बिट, हमेशा की तरह बाएँ से दाएँ पढ़े जाते हैं। पूरी पंक्ति को एक स्थान बाईं ओर शिफ्ट करना 2 से गुणा करने की समान संक्रिया है, क्योंकि किसी भी आधार में एक अंक को एक स्थान बाईं ओर ले जाने से उसका मान उस आधार से गुणा हो जाता है। द्विआधारी में केवल दो अंक होते हैं, इसलिए गुणक 2 है। तीन बार शिफ्ट करना इसे 8 से गुणा में संयोजित करता है, जो मेल खाता है कि संख्या 5 के साथ क्या करता है।