Nand2Tetris — الجزء الأول: من المنطق إلى المعالج › المشروع 4: لغة الآلة 4 / 6 السابق التالي

المشروع 4: لغة الآلة

المشروع 4: البرمجة بلغة الآلة

خلفية

كل منصة عتاد (hardware platform) مصممة لتنفيذ الأوامر بلغة آلة معيّنة، معبَّرًا عنها باستخدام رموز ثنائية متفق عليها. وكتابة البرامج مباشرةً بالرمز الثنائي ممكنة، لكنها غير ضرورية. وبدلًا من ذلك، يمكننا كتابة مثل هذه البرامج باستخدام لغة رمزية منخفضة المستوى تُسمى لغة التجميع (assembly)، ونترك ترجمتها إلى رمز ثنائي لبرنامج يُسمى المُجمِّع (assembler). في هذا المشروع سوف تكتب بعض برامج لغة التجميع منخفضة المستوى، وستظل ممتنًا للأبد للغات عالية المستوى مثل Java و Python. (في الحقيقة، يمكن أن تكون البرمجة بلغة التجميع مجزية للغاية، إذ تتيح تحكّمًا مباشرًا وكاملًا في الآلة الأساسية.)

الهدف

أن تحصل على لمحة عن البرمجة منخفضة المستوى بلغة الآلة، وأن تتعرف على منصة حاسوب Hack. وخلال العمل على هذا المشروع، سوف تألف عملية التجميع، أي الترجمة من لغة رمزية إلى لغة الآلة، وسوف تُقدّر بصريًا كيف يُنفَّذ الرمز الثنائي الأصلي على منصة العتاد الهدف. وسوف تُتعلَّم هذه الدروس في سياق كتابة واختبار برنامجين منخفضي المستوى، على النحو التالي.

البرامج

البرنامج الوصف سكربتات الاختبار
Mult.asm الضرب: في حاسوب Hack، تُعرف أيضًا كلمات RAM الـ16 العليا (RAM[0]...RAM[15]) باسم R0...R15. ومع وضع هذه المصطلحات في الاعتبار، يحسب هذا البرنامج القيمة R0R1 ويخزّن النتيجة في R2. ويفترض البرنامج أن R0>=0، وأن R1>=0، وأن R0R1<32768. ولا يلزم أن يختبر برنامجك هذه الشروط، بل يكفي أن يفترض أنها متحققة. استخدم محرّر نصوص عادي لكتابة برنامج Mult.asm بلغة التجميع الخاصة بـ Hack. واستخدم المُجمِّع (Hack Assembler) المُرفق لترجمة برنامج Mult.asm، فيُنتج ملف Mult.hack يحتوي على تعليمات Hack ثنائية. ثم حمّل سكربت Mult.tst المُرفق في مُحاكي الـ CPU. وهذا السكربت يحمّل برنامج Mult.hack ثم يُنفّذه. شغّل السكربت. وإذا ظهرت أي أخطاء، فصحّح برنامج Mult.asm وعدّله. ثم جمّع البرنامج، وأعد تشغيل سكربت Mult.txt، وهكذا.
Fill.asm معالجة الإدخال/الإخراج: يوضّح هذا البرنامج المعالجة منخفضة المستوى لجهازي الشاشة ولوحة المفاتيح، على النحو التالي. يُشغّل البرنامج حلقة لا نهائية تستمع إلى مدخلات لوحة المفاتيح. وعند الضغط على أي مفتاح (أي مفتاح)، يسوّد البرنامج الشاشة، أي يكتب "أسود" في كل بكسل؛ ويجب أن تظل الشاشة سوداء تمامًا ما دام المفتاح مضغوطًا. وعند عدم الضغط على أي مفتاح، يمسح البرنامج الشاشة، أي يكتب "أبيض" في كل بكسل؛ ويجب أن تظل الشاشة بيضاء تمامًا ما دام لا يوجد مفتاح مضغوط. ملاحظة تنفيذية: يجوز لبرنامجك أن يسوّد ويمسح بكسلات الشاشة بأي ترتيب مكاني/بصري، طالما أن الضغط على مفتاح باستمرار لمدة طويلة كافية يُنتج شاشة سوداء تمامًا، وعدم الضغط على أي مفتاح لمدة طويلة كافية يُنتج شاشة ممسوحة تمامًا. اكتب برنامج Fill.asm واختبره وصحّحه باتباع الإرشادات نفسها الواردة أعلاه لبرنامج Mult. وسكربت Fill.tst المُرفق، الذي لا يأتي معه ملف مقارنة، مُصمَّم للقيام بأمرين: (i) تحميل برنامج Fill.hack، و(ii) تذكيرك باختيار "no animation"، ثم اختبار البرنامج تفاعليًا عبر الضغط على بعض مفاتيح لوحة المفاتيح وإفلاتها. وسكربت FillAutomatic.tst المُرفق، إلى جانب ملف المقارنة المُرفق FillAutomatic.cmp، مُصمَّمان لاختبار برنامج Fill تلقائيًا، كما هو موصوف في توثيق سكربت الاختبار. ولإتمام الاختبار، اختبر برنامج Fill تفاعليًا وتلقائيًا.

العقد

اكتب واختبر البرنامجين الموصوفين أعلاه. وعند تنفيذهما على مُحاكي CPU المُرفق، يجب أن يُنتج برنامجاك النتائج التي تفرضها الاختبارات المحددة.

الموارد

تُوثَّق لغة التجميع الخاصة بـ Hack وتُناقش في الفصل 4.

والأداتان الصِّلتان بهذا المشروع هما مُحاكي CPU المُرفق، وهو إلزامي، والمُجمِّع المُرفق، وهو اختياري. التوضيح: عند تحميل ملف .asm في مُحاكي CPU، يترجم البرنامج التعليمات الرمزية إلى تعليمات Hack ثنائية أثناء التنفيذ، مما يُلغي الحاجة إلى عملية تجميع منفصلة.

انظر درس مُحاكي CPU التفاعلي (PPT، PDF) و، اختياريًا، درس المُجمِّع التفاعلي (PPT، PDF).

وملفات المشروع 4 متوفرة في مجلد nand2tetris/projects/04 لديك.

التنفيذ المقترح

- استخدم محرّر نصوص عادي لكتابة/تعديل برنامج التجميع الأول. ابدأ بتحميل ملف Mult.asm الهيكلي المُرفق وتعديله في projects/04/mult.

  • إذا أردت، يمكنك استخدام المُجمِّع المُرفق لترجمة برنامج Mult.asm إلى رمز Hack ثنائي. وهذا النشاط اختياري، إذ إن مُحاكي CPU يترجم ملفات .asm المحمّلة أثناء التنفيذ.

  • استخدم مُحاكي CPU المُرفق لتحميل برنامج Mult ثم تنفيذه. ويمكن فعل ذلك إما تفاعليًا، أو باستخدام سكربت Mult.tst المُرفق. وإذا كانت هناك أي أخطاء، فارجع إلى الخطوة 1.

  • كرّر الخطوات 1-3 للبرنامج الثاني (Fill.asm)، مع العمل في مجلد projects/04/fill.

نصيحة للتصحيح: لغة Hack حسّاسة لحالة الأحرف. ويحدث خطأ شائع عندما يكتب الشخص، مثلًا، "@foo" و"@Foo" في أجزاء مختلفة من برنامجه، معتقدًا أن كلا التسميتين تُعاملان باعتبارهما الرمز نفسه. في الواقع، يعامل المُجمِّع الاثنين باعتبارهما رمزين مختلفين. وهذا الخطأ يصعب اكتشافه، لذا ينبغي أن تكون على دراية به.

الأدوات

يمكن استخدام المُجمِّع (Hack Assembler) المُرفق إما في وضع الأوامر (من صدفة الأوامر)، أو تفاعليًا. ويتيح وضع التشغيل الأخير ملاحظة عملية الترجمة بصورة مرئية وخطوة بخطوة، كما هو موضح أدناه:

يمكن اختبار برامج لغة الآلة التي يُنتجها المُجمِّع بطريقتين مختلفتين. أولًا، يمكن تشغيل برنامج .hack الناتج في مُحاكي CPU المُرفق. أو بدلًا من ذلك، يمكن تشغيل البرنامج نفسه مباشرةً على عتاد Hack، باستخدام محاكي العتاد المُرفق المستخدم في المشاريع 1-3. ولعمل ذلك، يمكن تحميل شريحة Computer.hdl (المبنية في المشروع 5) في محاكي العتاد، ثم المتابعة لتحميل الرمز الثنائي (من ملف .hack) في ذاكرة التعليمات (Instruction Memory) للحاسوب، والتي تُسمى أيضًا ROM. وبما أننا سوف نكمل بناء منصة العتاد وشريحة Computer.hdl في المشروع التالي فقط، فإننا نوصي في هذه المرحلة باختبار البرامج على مستوى الآلة باستخدام مُحاكي CPU المُرفق.

يتضمّن مُحاكي CPU المُرفق (CPU Emulator) تمثيلًا لـ ROM، التي تُسمى أيضًا ذاكرة التعليمات (Instruction Memory)، والذي يُحمَّل فيه الرمز الثنائي، وتمثيلًا لـ RAM التي تحتفظ بالبيانات. ولسهولة الاستخدام، يتيح المُحاكي للمستخدم عرض الرمز المُحمَّل المقيم في ROM إما في وضع ثنائي، أو في وضع رمزي / تجميعي. بل إن مُحاكي CPU يتيح حتى تحميل رمز رمزي مكتوب بلغة التجميع مباشرةً في ROM، وفي هذه الحالة يترجم المُحاكي الرمز المُحمَّل إلى رمز ثنائي أثناء التنفيذ. وقد تبدو هذه الأداة وكأنها تُلغي الحاجة إلى المُجمِّع المُرفق، لكن هذا ليس صحيحًا. أولًا، يُظهر المُجمِّع المُرفق عملية الترجمة بصورة مرئية، لأغراض تعليمية. وثانيًا، يُنتج المُجمِّع ملفًا ثنائيًا دائمًا. ويمكن تنفيذ هذا الملف إما على مُحاكي CPU، كما نوضح أدناه، أو مباشرةً على منصة العتاد، كما سوف نفعل في المشروع التالي.