القرارات والحلقات
بشكل افتراضي، تنفذ وحدة المعالجة المركزية تعليماتك بالترتيب الذي تظهر به، من الأعلى إلى الأسفل. بحد ذاتها، لا يمكن لهذا الترتيب أبدًا أن يتخذ قرارًا أو يكرر عملًا. الفرع هو كيف يغادر البرنامج هذا المسار المستقيم: يختبر شرطًا، وعندما يتحقق الشرط، يوجه وحدة المعالجة المركزية للمتابعة من مكان مختلف بدلًا من السطر التالي. كل قرار وكل حلقة يأتيان من هذه الآلية الواحدة.
لا يوجد if أو for. أنت تبنيها من التسميات (مواضع مسماة) والفروع (القفز إلى موضع عندما يتحقق شرط). التسمية هي اسم يتبعه :.
لفهم كيفية تنفيذ فرع، تحتاج إلى معرفة عدّاد البرنامج (PC). PC هو سجل خاص، مخفي عن شفرتك، يحمل عنوان الذاكرة للتعليمة التي يتم تنفيذها. تكتب تعليمة الفرع قيمة جديدة في PC، لذا تجلب وحدة المعالجة المركزية تعليمتها التالية من تسميتك الهدف بدلًا من السطر التالي من الشفرة.
عائلة الفرع
كل فرع يقارن سجلين ويقفز إلى التسمية فقط عندما يتحقق الاختبار. عندما يفشل الاختبار، يستمر التنفيذ على السطر التالي. ستة اختبارات تشكل النواة:
beq a, b, label # تفرّع إذا كان a == bbne a, b, label # تفرّع إذا كان a != bblt a, b, label # تفرّع إذا كان a < b (بإشارة)bge a, b, label # تفرّع إذا كان a >= b (بإشارة)bltu a, b, label # تفرّع إذا كان a < b (بدون إشارة)bgeu a, b, label # تفرّع إذا كان a >= b (بدون إشارة)
و يختبران التساوي ويتجاهلان الإشارة. و يشكلان زوج الترتيب، أصغر من وأكبر من أو يساوي، ويقارنان السجلات كأعداد موقعة. و يجريان نفس المقارنات لكنهما يعالجان القيم كـغير موقعة، وهو ما يناسب العناوين أو العدّادات التي لا تكون سالبة أبدًا.
ماذا يعني موقّع وغير موقّع؟ يحمل السجل 32 بت، ويمكن قراءة نفس البتات بطريقتين. عند القراءة كـغير موقّعة، تشكل عددًا صحيحًا عاديًا من 0 حتى حوالي 4 مليارات. عند القراءة كـموقّعة، تُحسب البتة العليا كإشارة سالب، لذا تمثل نصف أنماط البتات أعدادًا سالبة. البتات نفسها لا تتغير. فقط طريقة قراءتك لها تتغير. لهذا توجد مجموعتان من المقارنات: استخدم الموقعة (، ) للأعداد العادية التي قد تكون سالبة، وغير الموقعة (، ) للقيم التي لا تكون سالبة أبدًا، مثل عناوين الذاكرة.
لا يوجد "فرع إذا كان أكبر" أو "فرع إذا كان أصغر أو يساوي" مباشر. تحصل عليهما بتبديل السجلين، ويوفر المجمّع و كفروع زائفة تجري التبديل نيابة عنك، لذا يصبح هو . اختصاران آخران: و يختبران سجلًا واحدًا مقابل الصفر، و يقفز بدون أي شرط.
li t0, 0 # المجموع = 0li t1, 1 # i = 1li t2, 6 # الحد = 6 (تكرار طالما i < 6)loop:bge t1, t2, done # يخرج من الحلقة عند i >= 6add t0, t0, t1 # المجموع += iaddi t1, t1, 1 # i++j loop # يعود للتحقق مجددًاdone:mv a0, t0 # يطبع المجموع (يجب أن يكون 15)li a7, 1ecallli a7, 10ecall
تتبعه. t0 يحمل المجموع الجاري (يبدأ من 0)، و t1 يحمل العدّاد i (يبدأ من 1)، و t2 يحمل الحد 6. في كل مرور عبر loop: يترك الحلقة بمجرد أن يصل i إلى 6. وإلا فإن يضيف i إلى المجموع، و يزيد i بواحد، و يقفز عائدًا للاختبار مرة أخرى. تضيف الحلقة 1 و2 و3 و4 و5، و done يطبع المجموع، 15.
يقارن bge بين t1 وt2 لتحديد ما إذا كانت الحلقة تستمر.
t1 هو 6، ينقل التحكم إلى done بدلًا من ترك الجسم يعمل مرة أخرى. هذا الاختبار هو ما يفصل المرور الذي يتكرر عن المرور الذي يتوقف.t1 ويقفز عدّاد البرنامج (pc) عائدًا إلى loop. في كل مرة يعود pc إلى loop، كان شرط الفرع خاطئًا، لذا تعمل الحلقة مرة أخرى.