كتابة معالج وبيئة بسيطة لذلك

مرحبا في هذه المقالة ، سأخبرك بالخطوات التي تحتاج إلى اتباعها لإنشاء معالج وبيئة بسيطة له.


هندسة مجموعة الأوامر (ISA)


تحتاج أولاً إلى تحديد ما سيكون عليه المعالج. المعلمات التالية مهمة:



يمكن تقسيم معماريات المعالج إلى نوعين وفقًا لحجم التعليمات (في الواقع ، هناك المزيد منها ، ولكن الخيارات الأخرى أقل شيوعًا):



الاختلاف الرئيسي بينهما هو أن معالجات RISC لها نفس حجم التعليمات. تعليماتهم بسيطة وتعمل بسرعة نسبيًا ، بينما يمكن أن يكون لمعالجات CISC أحجام تعليمات مختلفة ، قد يستغرق بعضها بعض الوقت.


قررت أن أجعل معالج RISC يشبه إلى حد كبير MIPS .


فعلت هذا لعدد من الأسباب:


  • من السهل جدًا إنشاء نموذج أولي لمثل هذا المعالج.
  • يتم نقل كل تعقيد هذا النوع من المعالج إلى برامج مثل المجمع و / أو المترجم.

فيما يلي الميزات الرئيسية للمعالج الخاص بي:


  • كلمة الآلة وحجم التسجيل - 32 بت
  • 64 سجل (بما في ذلك عداد الأوامر )
  • نوعان من التعليمات

نوع التسجيل (فيما يلي نوع التسجيل) يبدو كالتالي:


rtype


تكمن خصوصية هذه التعليمات في أنها تعمل مع ثلاثة سجلات.


النوع الفوري :


itype


تعمل التعليمات من هذا النوع مع سجلين ورقم.


OP هو رقم التعليمات التي سيتم تنفيذها (أو للإشارة إلى أن نوع التسجيل هذا).


R0 ، R1 ، R2 هي أرقام تسجيل تعمل كمعاملات للتعليمات.


Func هو حقل إضافي يستخدم للإشارة إلى نوع إرشادات نوع التسجيل .


Imm هو المجال الذي تتم فيه كتابة القيمة ، والتي نريد أن نقدمها بشكل صريح تعليمات كمعامل.


  • 28 تعليمات فقط

يمكن العثور على قائمة كاملة بالتعليمات في مستودع جيثب .


هنا اثنين منهم:


nor r0, r1, r2 

NOR عبارة عن تعليمة من نوع التسجيل تقوم بعمل منطقي OR NOT على السجلات r1 و r2 ، وبعد ذلك يكتب النتيجة في السجل r0.


لاستخدام هذه التعليمات ، تحتاج إلى تغيير حقل OP إلى 0000 وحقل Func إلى 0000000111 في نظام الأرقام الثنائية.


 lw r0, n(r1) 

LW هو نوع تعليمي فوري يقوم بتحميل قيمة ذاكرة عند r1 + n في سجل r0.


لاستخدام هذه التعليمات ، تحتاج أيضًا إلى تغيير حقل OP إلى 0111 وكتابة الرقم n في حقل IMM .


كتابة كود المعالج


بعد إنشاء ISA ، يمكنك البدء في كتابة المعالج.


لهذا ، نحن بحاجة إلى معرفة نوع من لغة وصف المعدات. هنا بعض منهم:


  • فيريلوج
  • VHDL (لا يجب الخلط بينه وبين السابق!)

اخترت فيريلوج ، لأنه البرمجة على ذلك جزء من دراستي الجامعية.


لكتابة معالج ، تحتاج إلى فهم منطق عمله:


  1. الحصول على التعليمات في عداد الأوامر (الكمبيوتر)
  2. تعليمات فك الشفرة
  3. تنفيذ التعليمات
  4. إضافة حجم أمر التعليمات المنفذة إلى العداد

وهكذا إلى ما لا نهاية.


اتضح أنك بحاجة إلى إنشاء عدة وحدات:



سنقوم بتحليل كل وحدة على حدة.


تسجيل الملف


يوفر ملف التسجيل الوصول إلى السجلات. مع ذلك ، تحتاج إلى الحصول على قيم بعض السجلات أو تغييرها.


في حالتي ، لدي 64 سجل. في أحد التسجيلات ، تتم كتابة نتيجة العملية على الاثنين الآخرين ، لذا أحتاج إلى إتاحة الفرصة لتغيير واحد فقط والحصول على القيم من الاثنين الآخرين.


فك


مفكك التشفير هو الوحدة المسؤولة عن تعليمات فك التشفير. يشير إلى العمليات التي يجب أن تقوم بها ALU والوحدات الأخرى.


على سبيل المثال ، يجب أن تضيف عبارة addi قيمة السجل $ صفر (تخزن دائمًا 0 ) و 20 وتضع النتيجة في السجل $ t0.


 addi $t0, $zero, 20 

عند هذه النقطة ، يقرر مفكك التشفير أن هذه التعليمات:


  • نوع فوري
  • يجب كتابة النتيجة في التسجيل

وينقل هذه المعلومات إلى الكتل التالية.


ALU


بعد أن يمر التحكم إلى ALU. عادة ما يقوم بإجراء جميع العمليات الحسابية والمنطقية ، وكذلك عمليات مقارنة الأرقام.


أي ، إذا أخذنا بعين الاعتبار نفس تعليمات addi ، عندها في هذه المرحلة تحدث إضافة 0 و 20 .


أخرى


بالإضافة إلى الكتل المذكورة أعلاه ، يجب أن يكون المعالج قادرًا على:


  • احصل على وتغيير القيم في الذاكرة
  • قم بالقفزات الشرطية

هنا وهناك يمكنك أن ترى كيف يبدو في الكود.


المجمع


بعد كتابة المعالج ، نحتاج إلى برنامج يحول أوامر النص إلى رمز الآلة حتى لا يتم ذلك يدويًا. لذلك ، تحتاج إلى كتابة المجمع.


قررت تنفيذه في لغة البرمجة C.


نظرًا لأن المعالج الخاص بي به بنية RISC ، من أجل تبسيط حياتي ، فقد قررت تصميم المجمّع بحيث يمكنني بسهولة إضافة التعليمات الزائفة الخاصة بي (مجموعات من عدة تعليمات أولية أو تعليمات زائفة أخرى).


يمكنك تنفيذ ذلك باستخدام بنية بيانات تقوم بتخزين نوع التعليمات وتنسيقها ومؤشر إلى دالة تقوم بإرجاع رموز تعليمات الجهاز واسمها.


يبدأ البرنامج العادي بإعلان قطعة.


هناك جزءان . نص كاف بالنسبة لنا - حيث سيتم تخزين التعليمات البرمجية المصدر لبرامجنا - وبيانات. - حيث سيتم تخزين بياناتنا وثوابتنا .


قد تبدو التعليمات كما يلي:


 .text jie $zero, $zero, $zero #  addi $t1, $zero, 2 # $t1 = $zero + 2 lw $t1, 5($t2) # $t1 = *($t2 + 5) syscall 0, $zero, $zero # syscall(0, 0, 0) la $t1, label# $t1 = label 

أولاً ، يشار إلى اسم التعليمات ، ثم المعاملات.


في البيانات. يشار إلى بيانات البيانات.


 .data .byte 23 #   1  .half 1337 #   2  .word 69000, 25000 #   4  .asciiz "Hello World!" #     ( ) .ascii "12312009" #   ( ) .space 45 #  45  

يجب أن يبدأ الإعلان بنقطة واسم نوع بيانات ، متبوعًا بالثوابت أو الوسيطات.


من السهل تحليل (مسح) ملف التجميع على النحو التالي:


  1. أولاً ، امسح الجزء
  2. إذا كان مقطع بيانات. ، فإننا نقوم بتحليل أنواع بيانات مختلفة أو مقطع نص
  3. إذا كان مقطع نص .t ، فإننا نقوم بتحليل الأوامر أو مقطع البيانات

للعمل ، يحتاج المجمّع إلى مراجعة الملف المصدر مرتين. في المرة الأولى التي ينظر فيها إلى ما يعوض عن الروابط (التي تخدمها) ، فإنها عادة ما تبدو كما يلي:


  la $s4, loop #   loop  s4 loop: # ! mul $s2, $s2, $s1 # s2 = s2 * s1 addi $s1, $s1, -1 # s1 = s1 - 1 jil $s3, $s1, $s4 #  s3 < s1     

وفي المسار الثاني ، يمكنك بالفعل إنشاء ملف.


الملخص


في المستقبل ، يمكنك تشغيل ملف الإخراج من المجمع على معالجنا وتقييم النتيجة.


أيضا ، يمكن استخدام المجمع الجاهزة في المترجم C. ولكن هذا لاحقًا.


المراجع:


Source: https://habr.com/ru/post/ar430680/


All Articles