inspection 3
inspection 3

@aljabr_wd

25 تغريدة 3 قراءة May 04, 2024
#ثريد بعض اساسيات وحدة المعالجة المركزية (CPU) والرمات في تنفيذ لغة الآلة Assembly
الدور الأساسي لوحدة المعالجة المركزية (CPU)في تنفيذ رمز الآلة لبرنامج معين.رمز الآلة،أو لغة الآلة،هو مجموعة من التعليمات التي تقوم وحدة المعالجة المركزية بتنفيذها.كل تعليمة هي أمر بدائي ينفذ عملية محددة مثل نقل البيانات،أو تغيير تدفق تنفيذ البرنامج،أو أداء عمليات حسابية وغيرها.
تتمثل تعليمات وحدة المعالجة المركزية في شكل ست عشري(HEX).بسبب تعقيده،فمن المستحيل على البشر استخدامه في شكله الطبيعي.لذلك،يتم ترجمة نفس رمز الآلة إلى رمز ذو طابع أكثر قراءة،وهو ما يُعرف بلغة التجميع(ASM).أكثر لغتين شهرة هماNASM (المجمع العام)وMASM(مجمع مايكروسوفت).
مثال في الشريحة التالية هو رمز الآلة لبرنامج يُدعى sample1_helloworld.exe. يتم توضيح هذا لاحقًا، لكن في الوقت الحالي، من المفيد فهم الفروق بين لغة الآلة ولغة التجميع.
كل وحدة معالجة مركزية (CPU) لديها معمارية مجموعة تعليمات محددة (ISA). تعتبر هذه المعمارية مجموعة التعليمات التي يجب على المبرمج (أو compiler) فهمها واستخدامها لكتابة برنامج بشكل صحيح لتلك الوحدة المعالجة المركزية والجهاز الذي يعمل عليه.
بمعنى آخر، تمثل معمارية التعليمات ما يمكن للمبرمج رؤيته: الذاكرة، registers، instructions،إلخ.وهي توفر جميع المعلومات اللازمة لمن يرغب في كتابة برنامج بلغة الآلة لتلك الوحدة المعالجة المركزية.
عدد البتات سواء كان 32 أو 64، يشير إلى عرض سجلات وحدة المعالجة المركزية (CPU). تحتوي كل وحدة معالجة مركزية على مجموعة ثابتة من السجلات التي يتم الوصول إليها عند الحاجة. يمكنك التفكير في السجلات كمتغيرات مؤقتة يستخدمها وحدة المعالجة المركزية للحصول على البيانات وتخزينها.
أحد أكثر مجموعات تعليمات معمارية شيوعًا هي مجموعة تعليمات x86 (or
architecture) والتي نشأت من Intel 8086. تعتبر الاختصارات x86 تحديدًا لمعالجات 32 بت، بينما x64 (المعروفة أيضًا باسم x86_64 أو AMD64) تحدد الإصدارات بت 64.
Registers:هي مكون رئيسي في هذه الوحدة التدريبية. على الرغم من أن جميع السجلات تشكل جزءًا صغيرًا من الذاكرة في وحدة المعالجة المركزية وتستخدم لتخزين البيانات مؤقتًا، فإنه من المهم معرفة أن بعضها له وظائف محددة، بينما يتم استخدام البعض الآخر لتخزين البيانات بشكل عام.
تتلخص الجدول التالي الثمانية registers الغرض العام. يُلاحظ أن تسمية الregisters تشير إلى بنية x86.سنرى كيف تختلف الأسماء للبتات 64 و32 و16 و8.
على الرغم من أن هذه المعلومات قد تبدو مُرهِقة، سيكون كل شيء أكثر وضوحًا عندما نتحدث عن طرد (stack.).
تسمية الregisters في معالجات الـ 8 بت القديمة كانت تشمل registers 16 بت مُقسمة إلى جزأين:
- بايت منخفض، يُميز بـ L في نهاية الاسم، و
- بايت مرتفع، يُميز بـ H في نهاية الاسم.
تجمع تسمية الـ 16 بت بين الـ L والـ H، وتستبدلهما بـ X. أما بالنسبة لregisters Stack Pointer، وBase Pointer، والمصدر والوجهة، فإنها ببساطة تقوم بإزالة الـ L.
في العرض البت 32، يُسبق اختصار لregisters بـ E، مما يعني "موسع". أما في العرض البت 64، فإن الـ E يُستبدل بـ R.
ملخص لقواعد تسمية البيانات في بيئة 32 بت مع توضيح للقاعدة في بيئة 64 بت
العملية (Process) مقسمة إلى أربع مناطق: النص (Text)، البيانات (Data)، الكومة (Heap)، والطرد (Stack).
منطقة النص، أو الشريحة التعليمية، ثابتة بواسطة البرنامج وتحتوي على شفرة البرنامج (التعليمات). تُعتبر هذه المنطقة كقراءة فقط، حيث لا ينبغي للبرنامج تغييرها أثناء التنفيذ.
المنطقة البيانية (Data region) مقسمة إلى بيانات مُبادَئة (Initialized data) وبيانات غير مُبادَئة (Uninitialized data). تشمل البيانات المُبادَئة عناصر مثل المتغيرات الثابتة والعامة التي تم تعريفها مسبقًا ويمكن تعديلها.
أما البيانات غير المُبادَئة، والتي يُطلق عليها اسم Block Started by Symbol (BSS)، فتهيئ أيضًا المتغيرات التي يتم تهيئتها بالصفر أو التي ليس لها تهيئة صريحة (مثلاً: static int t).
بالنسبة للذاكرة في البرامج، الجزء التالي هو الخريطة العامة:
1. القسم الثابت (BSS Segment):يستخدم لتخزين المتغيرات الثابتة والمتعددة البيانات التي لم يتم تهيئتها بقيمة محددة في الشفرة، وعادةً تبدأ في بداية الذاكرة.
2.المنطقة العامة (Data Segment): تستخدم لتخزين المتغيرات التي تم تهيئتها بقيمة محددة في الشفرة. عادة ما تلي الـ BSS.
3.الحشو (Heap):يبدأ مباشرة بعد الـ BSS ويستخدم لتخصيص مساحة إضافية في الذاكرة أثناء تشغيل البرنامج باستخدام مكالمات النظام brk وsbrk، والتي تستخدمها الوظائف مثل malloc وrealloc وfree لطلب وتحرير الذاكرة. يمكن توسيع حجم منطقة البيانات بهذه الطريقة. للمزيد: man7.org
4.الكومة (Stack):يعتبر أهم الهياكل التي سنتعامل معها لأغراضنا. تُستخدم الكومة لتخزين المتغيرات المحلية وإدارة سير التنفيذ للدوال. تنمو الكومة أسفليًا بينما يزيد عمق الاستدعاء للدوال.
هذه نبذة موجزة عن توزيع الذاكرة في البرنامج.
الكومة (Stack) هي مجموعة ذاكرة يتم استخدامها بنظام "الدخول الأخير خروج أولاً" (Last-in-First-out - LIFO). تقع في الجزء العلوي من الذاكرة. يمكنك التفكير في الكومة كمصفوفة تُستخدم لحفظ عناوين العودة من الدوال، وتمرير معاملات الدوال، وتخزين المتغيرات المحلية.
غرض سجلESP(مؤشر الكومة)هو تحديد أعلى الكومة،ويتم تعديله في كل مرة يتم فيها إدخال قيمة(PUSH)أو إخراجها(POP).عند إضافة قيمة إلى الكومة باستخدام عملية PUSH،يقومESPبالتحرك ليشير إلى العنصر الجديد في الكومة.
وعند إزالة قيمة من الكومة باستخدام عملية POP، يقوم ESP بالتحرك ليشير إلى العنصر التالي في الكومة.
وبهذه الطريقة، يتم تعديل قيمة مؤشر الكومة (ESP) تلقائيًا مع كل عملية إضافة أو إزالة في الكومة.
تم اتخاذ قرار بأن الحشو (Heap) سيبدأ من العناوين الأقل وينمو باتجاه الأعلى، بينما سيبدأ الكومة (Stack) من نهاية الذاكرة وينمو باتجاه الأسفل.
بمعنى آخر، يتم تخصيص المساحة للحشو من النهاية السفلى للذاكرة ويمكن توسيعها تدريجيا نحو العناوين الأعلى.
بينما يتم تخصيص المساحة للكومة من النهاية العليا للذاكرة ويمكن توسيعها تدريجيا نحو العناوين الأدنى. هذا الاختيار يسمح بتحديد سهولة تحديد الحدود بين الحشو والكومة وتخصيص الذاكرة بشكل فعال للتطبيقات المختلفة.

جاري تحميل الاقتراحات...