المتجهات: الفهرسة حسب الموضع
المتجه هو مصفوفة: سلسلة من الأرقام مخزنة بجانب بعضها في الذاكرة. في الدرس السابق جمعت عنصرًا واحدًا بتحريك المؤشر للأمام 4 بايت لكل عنصر. تعمل الطريقة نفسها هنا. هناك طريقة شائعة أخرى للوصول إلى عنصر: بالفهرس. الفهرس هو موضع العنصر محسوبًا من البداية، حيث يكون فهرس العنصر الأول 0، والثاني 1، وهكذا.
جمع متجه عن طريق تحريك مؤشر
.dataa: .word 5, 10, 15, 20 # أربعة عناصر.textla t0, a # t0 = عنوان ali t1, 4 # t1 = عدد العناصر المتبقيةli t2, 0 # t2 = المجموع الجاريloop:beq t1, zero, donelw t3, 0(t0) # يحمّل العنصر الحاليadd t2, t2, t3 # يضيف إلى المجموعaddi t0, t0, 4 # ينتقل إلى الكلمة التالية (4 بايتات)addi t1, t1, -1 # أقل بواحدj loopdone:mv a0, t2 # يطبع المجموع: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
تعمل الحلقة كما يلي. يحمل 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]. هذا الإزاحة هي طريقة قوى الاثنين نفسها من درس الحساب، وهي الطريقة القياسية لتحجيم فهرس بحجم كلمة.
a[0]: الفهرس 0، الإزاحة 0.
i كموضع، والعنوان الذي ينتجه ذلك الموضع بعد أن تحجّمه بمقدار 4 وتضيفه إلى الأساس. الأرقام الست عشرية هي العناوين الفعلية التي يشغلها a عندما يشغّل المحاكي هذا البرنامج. الهدف هو توقع العنوان التالي قبل ظهوره. يتيح لك ذلك قراءة داخل حلقة متزايدة، أو a[i] في لغة شبيهة بـ C، وتصوّر عنوان الذاكرة الذي تلمسه بدلًا من التعامل مع الترميز كصندوق أسود.جمع متجه عبر الفهرس
.dataa: .word 5, 10, 15, 20 # أربعة عناصر.textla t0, a # t0 = العنوان الأساسي لـ ali t1, 4 # t1 = عدد العناصرli t2, 0 # t2 = الفهرس، يبدأ من 0li t3, 0 # t3 = مجموع متراكمloop:beq t2, t1, doneslli 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 loopdone:mv a0, t3 # يطبع المجموع: 5+10+15+20 = 50li a7, 1ecallli a7, 10ecall
تعمل الحلقة كما يلي. t2 هو الفهرس، بدءًا من 0. في كل دورة، تنهي الحلقة عندما يصل الفهرس إلى 4، وهو عدد العناصر المحمول في t1. تحوّل الفهرس إلى إزاحة بالبايت. تضيف تلك الإزاحة إلى عنوان الأساس في t0 لإنتاج عنوان a[index]. تحمّل القيمة المخزنة هناك. تُضاف تلك القيمة إلى المجموع الجاري في t3، وتتقدم إلى الفهرس التالي. بعد أربع دورات (5 + 10 + 15 + 20)، تطبع done القيمة 50.
جمع متجهين، عنصرًا بعنصر
.dataa: .word 3, 6, 9, 12 # المتجه الأولb: .word 1, 2, 3, 4 # المتجه الثانيc: .space 16 # مكان لأربع كلمات نتيجة.textla t0, a # العنوان الأساسي لـ ala t1, b # العنوان الأساسي لـ bla t2, c # العنوان الأساسي لـ cli t3, 0 # الفهرس، يبدأ من 0li t4, 4 # عدد العناصرli s0, 0 # المجموع الجاريloop:beq t3, t4, doneslli t5, t3, 2 # إزاحة البايت = الفهرس * 4add 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 loopdone:mv a0, s0 # يطبع المجموع: 4+8+12+16 = 40li a7, 1ecallli a7, 10ecall
تعمل الحلقة كما يلي. تحوّل الفهرس t3 إلى إزاحة بالبايت. إضافتها إلى كل مؤشر أساس (t0، t1، t2) تعطي عناوين a[i] وb[i] وc[i]. في كل دورة، يُحمَّل العنصران معًا، ويُجمعان، ويُخزَّنان في c، ويُضافان إلى المجموع الجاري في s0. تتقدم إلى الفهرس التالي، وتتكرر الحلقة حتى تُعالج العناصر الأربعة جميعها.
