P01NT
0x3 04/08

أنماط العنونة

أنماط العنونة في معمارية المعالجات: الفورية والمباشرة وغير المباشرة والمسجلة والفهرسة والأساس+إزاحة، ثم بنية التعليمة حقولاً وطولاً: الثابت في ARM مقابل المتغير في x86.

· 4 دقائق قراءة · 810 كلمة
المحتويات

بسم الله الرحمن الرحيم.

في المقال السابق تحدثنا عن الـ ISA وقلنا إنها تحدد أموراً كثيرة مثل (Instructions، Data Types، Registers، Memory Access وAddressing Modes). وبما أن كل المصطلحات السابقة مرت معنا ما عدا أنماط العنونة (Addressing Modes)، فهذا مقالها إن شاء الله.

تنبيه قبل المتابعة: إن ورد مني أي تقصير في شرح جزئية معينة فذلك طبيعي؛ فأنا لا أدّعي الكمال في هذه السلسلة ولا في غيرها، ولكن أسعى إليه. فإن رأيت مفهوماً غير صحيح أو إشكالاً في شيء، يمكنك الإيضاح للإفادة العامة. وأرجو من الله أن يجعل هذا العمل خالصاً لوجهه الكريم.

أنماط العنونة (Addressing Modes)

باختصار: هي الطرق التي تحدد للمعالج كيفية الحصول على البيانات أو العناوين التي يحتاجها لتنفيذ التعليمات في لغة الآلة أو التجميع. ولها عدة أنماط:

• العنونة الفورية (Immediate Addressing): في هذا النمط تكون قيمة المعامل مضمنة مباشرةً في التعليمة نفسها (الحقل الخاص بالمعامل يحوي قيمة ثابتة تستخدم كما هي). يؤدي ذلك إلى عدم الحاجة للوصول إلى الذاكرة لجلب المعامل.

mov  al, 5          ; ينقل القيمة 5 مباشرة إلى المسجل AL

• العنونة المباشرة (Direct Addressing): في هذا النمط يحتوي الحقل المخصص على عنوان الذاكرة الفعلي للمعامل (التعليمة تتضمن عنوان الذاكرة بشكل صريح). عند التنفيذ يستخدم هذا العنوان للوصول مباشرة إلى موقع الذاكرة الذي يحوي المعامل.

mov  ax, [0x0302]   ; ينقل محتوى العنوان 0x0302 إلى المسجل AX

• العنونة غير المباشرة (Indirect Addressing): في هذا النمط يشير الحقل المخصص في التعليمة إلى خلية ذاكرة أو مسجل يحوي عنوان المعامل (ولذلك يتطلب الأمر هنا وصولين إلى الذاكرة: الأول لقراءة العنوان الفعلي، والثاني للوصول إلى المعامل الحقيقي).

mov  ax, [bx]       ; ينقل القيمة المخزنة في العنوان الذي يحمله BX إلى AX

وللعنونة غير المباشرة مقابل واضح في C: المؤشرات. مثلاً:

int x = 10;
int *p = &x;
int y = *p;         // p يحمل عنوان x، ثم يستخرج *p قيمة x من ذلك العنوان

• العنونة المسجلة (Register Addressing): هنا يكون المعامل — أي بيانات العملية — محفوظاً في مسجل داخل المعالج (يتعامل المعالج مع المسجلات مباشرة دون الرجوع إلى الذاكرة)، ولهذا يعد هذا النمط سريعاً جداً.

mov  ax, cx         ; ينقل محتوى CX إلى AX

• العنونة بالفهرسة (Indexed Addressing): في هذا النمط يُحسب العنوان الفعلي للمعامل بجمع قيمة مسجل الفهرس (Index) مع إزاحة ثابتة (Offset).

mov  ax, [si + 5]   ; العنوان الفعلي = محتوى SI + 5

يُضاف الرقم 5 (Offset) إلى محتوى المسجل SI (Index) للحصول على العنوان النهائي. ويستخدم هذا النمط غالباً للوصول إلى عناصر مصفوفة: لو افترضنا أن SI يحمل عنوان بداية مصفوفة عناصرها بحجم بايت واحد، فإن التعليمة السابقة تصل إلى العنصر السادس.

ومثاله في C:

int arr[10];
int x = arr[3];

يمكن اعتباره نمط فهرسة حيث: العنوان = (عنوان بداية arr) + sizeof(int) × 3.

• العنونة بالأساس + إزاحة (Base + Offset Addressing): هنا يخزن المسجل قيمة العنوان الأساسي (Base)، ويضاف إليه إزاحة ثابتة مضمنة ضمن التعليمة.

mov  eax, [ebp + 8]   ; EBP (مسجل الأساس) + الإزاحة 8

يُجمع محتوى مسجل الأساس EBP مع القيمة 8 للوصول إلى عنوان المعامل المطلوب. ويفيد هذا النمط في الوصول إلى معاملات الدوال والمتغيرات المحلية داخل إطار الستاك بالنسبة إلى مؤشر الإطار، وكذلك حقول الهياكل Structs — أي نمط ptr+offset العام.

بنية التعليمة (Instruction Format)

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

الحقول الأساسية

- حقل الأمر (Opcode Field): يحدد نوع العملية التي سينفذها المعالج — حسابية كانت أم منطقية أم نقل بيانات أم قفزاً… إلخ. باختصار هو مجموعة البتات التي ترمز للعملية المطلوبة، وعدد بتاته يعتمد على عدد العمليات المدعومة: إذا كان لديك 2ⁿ عملية مختلفة فسيحتاج الحقل إلى n بتات لتشفيرها:

n = 1 => 2¹ = عمليتان (0 أو 1)
n = 2 => 2² = أربع عمليات (00، 01، 10، 11)

وهذا المبدأ الأساسي في تصميم أنظمة الترميز.

- حقول المعاملات (Operand Fields): تشير إلى البيانات أو العناوين الداخلة في العملية؛ وتحتوي العناوين الفعلية أو مواقعها: قد تشير إلى سجلات داخلية، أو عناوين في الذاكرة، أو قيم ثابتة — بحسب نمط العنونة المستخدم.

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

مثال

add R1, R2, R3
  • Opcode: add — يشير إلى عملية الجمع.
  • operand1: R1 — الوجهة التي ستخزن النتيجة.
  • operand2: R2 — المعامل الأول.
  • operand3: R3 — المعامل الثاني.

فصيغة التعليمة إذن هيكل بتاتي يقسم التعليمة إلى هذه الحقول:

مثال لبنية تعليمة: بت العنونة وبتات الأوبكود وبتات العنوان شكل (1): مثال لتقسيم بتات التعليمة إلى حقول

كما ترى: أول بت لطريقة العنونة (مباشرة / غير مباشرة)، وثلاثة بتات للأوبكود، واثنا عشر بتاً للعناوين.

ما الذي يحدد طول الصيغة؟

طول الصيغة (Fixed vs Variable Length): بعض المعماريات تستخدم تعليمات بطول ثابت يُعرف عدد بتاته مسبقاً، وأخرى تستخدم طولاً متغيراً.

مثلاً: جميع تعليمات معالجات ARM طولها ثابت 4 بايتات، مما يسهل عملية فك التشفير وتحديد موقع كل حقل داخل التعليمة. بينما تستخدم معالجات x86 تعليمات بطول متغير (تذكرنا من 1 إلى 15 بايتاً في المقال السابق)، وهذا يجعل صيغة التعليمات أكثر مرونة في الترميز.


اسأل الله أن يوسع علينا بسطة في العلم والعمل والرزق، والسلام عليكم ورحمة الله وبركاته.