المتجهات: الفهرسة حسب الموضع

المتجهات: الفهرسة حسب الموضع

المتجه هو مصفوفة: سلسلة من الأرقام مخزنة بجانب بعضها في الذاكرة. في الدرس السابق جمعت عنصرًا واحدًا بتحريك المؤشر للأمام 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 هو حجم الكلمة بالبايت. يولّد المترجم هذا الحساب نفسه لـ a[i] في لغة مثل C. الفهرس نفسه لا يصل إلى الذاكرة أبدًا. فقط العنوان المحسوب منه يفعل ذلك.

فهرسة العنوان باستخدام إزاحة
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]. هذا الإزاحة هي طريقة قوى الاثنين نفسها من درس الحساب، وهي الطريقة القياسية لتحجيم فهرس بحجم كلمة.

حساب العنوان
العنوان=base+0×4=base+0
a[0]3
0x10010000
a[1]6
0x10010004
a[2]9
0x10010008
a[3]12
0x1001000c

a[0]: الفهرس 0، الإزاحة 0.

يتحرك شريط المؤشر وشارة الست عشري معًا بينما يتنقل الفهرس عبر 0، 1، 2، 3. يقدمان الحقيقة نفسها في شكلين: i كموضع، والعنوان الذي ينتجه ذلك الموضع بعد أن تحجّمه بمقدار 4 وتضيفه إلى الأساس. الأرقام الست عشرية هي العناوين الفعلية التي يشغلها a عندما يشغّل المحاكي هذا البرنامج. الهدف هو توقع العنوان التالي قبل ظهوره. يتيح لك ذلك قراءة داخل حلقة متزايدة، أو a[i] في لغة شبيهة بـ C، وتصوّر عنوان الذاكرة الذي تلمسه بدلًا من التعامل مع الترميز كصندوق أسود.

جمع متجه عبر الفهرس

اجمع متجهًا باستخدام الفهرس
.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 # مكان لأربع كلمات نتيجة
.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، هو كيفية ترجمة كل وصول إلى مصفوفة، في أي لغة. تذكّره: يستخدم الدرس التالي الفكرة نفسها مرتين في آن واحد للوصول إلى مصفوفة.