वेक्टर: स्थिति के अनुसार अनुक्रमण

वेक्टर: स्थिति के अनुसार अनुक्रमण

वेक्टर एक ऐरे है: संख्याओं का एक अनुक्रम जो मेमोरी में एक-दूसरे के बगल में संग्रहीत होता है। पिछले पाठ में आपने एक को जोड़ते हुए एक पॉइंटर को प्रत्येक तत्व के लिए 4 बाइट आगे बढ़ाया था। वही विधि यहाँ भी काम करती है। एक तत्व तक पहुँचने का एक और सामान्य तरीका है: इंडेक्स द्वारा। एक इंडेक्स वह स्थिति है जिसे शुरुआत से गिना जाता है, जहाँ पहला तत्व इंडेक्स 0 रखता है, दूसरा इंडेक्स 1 रखता है, और इसी तरह।

पॉइंटर को आगे बढ़ाकर एक वेक्टर का योग करें

एक पॉइंटर को आगे बढ़ाकर वेक्टर का योग करें
.data
a: .word 5, 10, 15, 20 # चार तत्व
.text
la t0, a # t0 = a का पता
li t1, 4 # t1 = शेष तत्वों की संख्या
li t2, 0 # t2 = चालू योग
loop:
beq t1, zero, done
lw t3, 0(t0) # मौजूदा तत्व लोड करता है
add t2, t2, t3 # योग में जोड़ता है
addi t0, t0, 4 # अगले वर्ड पर आगे बढ़ता है (4 बाइट्स)
addi t1, t1, -1 # एक कम बचा
j loop
done:
mv a0, t2 # कुल योग प्रिंट करता है: 5+10+15+20 = 50
li a7, 1
ecall
li a7, 10
ecall

लूप इस प्रकार चलता है। t0 में a का पता होता है, और t1 में शेष तत्वों की संख्या होती है, जो 4 से शुरू होती है। प्रत्येक चक्र में, गणना के शून्य होने पर लूप समाप्त कर देता है। t0 में दिए गए पते पर स्थित तत्व को लोड करता है। उस मान को चालू योग में जोड़ता है। पॉइंटर को अगले शब्द तक बढ़ाता है। गणना को घटाता है। चार चक्रों के बाद (5 + 10 + 15 + 20), done 50 प्रिंट करता है। यह वही पैटर्न है जो मेमोरी पाठ में उपयोग किया गया था, अब एक वेक्टर पर लागू किया गया है।

सूचकांक से पता तक

इंडेक्सिंग एक आधार पॉइंटर और एक स्थिति से एक पता की गणना करती है: address = base + index * 4। 4 एक शब्द का बाइट्स में आकार है। एक कंपाइलर C जैसी भाषा में a[i] के लिए यही गणना उत्पन्न करता है। इंडेक्स स्वयं कभी मेमोरी का उपयोग नहीं करता। केवल उससे गणना किया गया पता ही करता है।

शिफ्ट का उपयोग करके पते तक पहुँचने के लिए इंडेक्स
slli t5, t3, 2 # t5 = इंडेक्स * 4 (वर्ड का आकार)
add t6, t0, t5 # t6 = element[index] का पता
lw t6, 0(t6) # t6 = element[index]

t3 में इंडेक्स को 2 बिट बाईं ओर शिफ्ट करता है, जो इसे 4 से गुणा करता है (दो दोहरीकरण: 2 x 2), जो एक शब्द का आकार है। परिणाम को आधार पॉइंटर में जोड़ने पर element[index] का पता मिलता है। यह शिफ्ट अंकगणित पाठ की वही दो-की-घात विधि है, और यह एक इंडेक्स को एक शब्द के आकार से मापने का मानक तरीका है।

पता की गणना
पता=बेस+0×4=बेस+0
a[0]3
0x10010000
a[1]6
0x10010004
a[2]9
0x10010008
a[3]12
0x1001000c

a[0]: index 0, offset 0.

पॉइंटर बार और हेक्स बैज एक साथ चलते हैं जब इंडेक्स 0, 1, 2, 3 से गुजरता है। वे एक ही तथ्य को दो रूपों में प्रस्तुत करते हैं: i एक स्थिति के रूप में, और वह पता जो वह स्थिति द्वारा इसे 4 से मापने और आधार में जोड़ने के बाद उत्पन्न करती है। हेक्स संख्याएँ वे वास्तविक पते हैं जो सिम्युलेटर के इस प्रोग्राम को चलाने पर a रखता है। लक्ष्य अगले पते का अनुमान लगाना है इससे पहले कि वह प्रकट हो। यह आपको एक बढ़ते लूप के अंदर पढ़ने, या C जैसी भाषा में a[i] पढ़ने, और जिस मेमोरी पते को वह छूता है उसकी कल्पना करने देता है, बजाय इसके कि आप संकेतन को एक ब्लैक बॉक्स मानें।

इंडेक्स द्वारा वेक्टर का योग

इंडेक्स का उपयोग करके एक वेक्टर का योग करें
.data
a: .word 5, 10, 15, 20 # चार तत्व
.text
la t0, a # t0 = a का आधार पता
li t1, 4 # t1 = तत्वों की संख्या
li t2, 0 # t2 = सूचकांक, 0 से शुरू होता है
li t3, 0 # t3 = संचयी कुल
loop:
beq t2, t1, done
slli t4, t2, 2 # t4 = सूचकांक * 4 (बाइट ऑफ़सेट)
add t5, t0, t4 # t5 = a[index] का पता
lw t5, 0(t5) # t5 = a[index]
add t3, t3, t5 # total += a[index]
addi t2, t2, 1 # अगले इंडेक्स पर आगे बढ़ता है
j loop
done:
mv a0, t3 # कुल योग प्रिंट करता है: 5+10+15+20 = 50
li a7, 1
ecall
li a7, 10
ecall

लूप इस प्रकार चलता है। t2 इंडेक्स है, जो 0 से शुरू होता है। प्रत्येक चक्र में, लूप को तब समाप्त करता है जब इंडेक्स 4 तक पहुँच जाता है, जो t1 में रखी तत्वों की संख्या है। इंडेक्स को बाइट ऑफ़सेट में बदलता है। उस ऑफ़सेट को t0 में आधार पते में जोड़कर a[index] का पता उत्पन्न करता है। वहाँ संग्रहीत मान को लोड करता है। वह मान t3 में चालू योग में जोड़ा जाता है, और अगले इंडेक्स पर बढ़ता है। चार चक्रों के बाद (5 + 10 + 15 + 20), done 50 प्रिंट करता है।

दो वेक्टरों को तत्व-दर-तत्व जोड़ना

c[i] = a[i] + b[i]
.data
a: .word 3, 6, 9, 12 # पहला वेक्टर
b: .word 1, 2, 3, 4 # दूसरा वेक्टर
c: .space 16 # परिणाम के लिए 4 वर्ड की जगह
.text
la t0, a # a का आधार पता
la t1, b # b का आधार पता
la t2, c # c का आधार पता
li t3, 0 # इंडेक्स, 0 से शुरू
li t4, 4 # तत्वों की संख्या
li s0, 0 # चालू योग
loop:
beq t3, t4, done
slli t5, t3, 2 # बाइट ऑफ़सेट = इंडेक्स * 4
add t6, t0, t5 # a[index] का पता
lw t6, 0(t6) # a[index] का मान
add a0, t1, t5 # b[index] का पता
lw a0, 0(a0) # b[index] का मान
add t6, t6, a0 # a[index] + b[index]
add a0, t2, t5 # c[index] का पता
sw t6, 0(a0) # c[index] = a[index] + b[index]
add s0, s0, t6 # योग += c[index]
addi t3, t3, 1 # अगले इंडेक्स पर आगे बढ़ता है
j loop
done:
mv a0, s0 # कुल योग प्रिंट करता है: 4+8+12+16 = 40
li a7, 1
ecall
li a7, 10
ecall

लूप इस प्रकार चलता है। इंडेक्स t3 को बाइट ऑफ़सेट में बदलता है। इसे प्रत्येक आधार पॉइंटर (t0, t1, t2) में जोड़ने पर a[i], b[i], और c[i] के पते मिलते हैं। प्रत्येक चक्र में, दोनों तत्व लोड किए जाते हैं, एक साथ जोड़े जाते हैं, c में संग्रहीत किए जाते हैं, और s0 में चालू योग में जोड़े जाते हैं। अगले इंडेक्स पर बढ़ता है, और लूप तब तक दोहराता है जब तक सभी चार तत्व संसाधित न हो जाएँ।

💡
यह इंडेक्स पैटर्न, base + index * element size, किसी भी भाषा में हर ऐरे एक्सेस इसी तरह कंपाइल होता है। इसे ध्यान में रखें: अगला पाठ एक मैट्रिक्स तक पहुँचने के लिए एक ही विचार का दो बार एक साथ उपयोग करता है।