Barakat Soror
Barakat Soror

@barakatsoror

11 تغريدة 369 قراءة Dec 02, 2019
1. الـ memory segmentation آلية إدارة ذاكرة قديمة بدأت من معالج Intel 8086 عام 1978، رغم قدمها واستخدامها فقط عندما يعمل المعالج كـ 16 بت في وضع الـ real-mode، إلا أن فهمها مهم لأن الـ segment registers مثل gs و fs لاتزال مستخدمة ولن يتضح معناها إلا بالرجوع لاستخدامها الأصلي…
2. الفكرة في الـ segmented memory بشكل عام أنك لا تشير مباشرة للعنوان في الذاكرة، لكن تستخدم offset من بداية عنوان قابل للتغير يسمى بالـ base address ويمثّل عنوان بداية الـ segment، هكذا يمكننا أن نغير مكان البرنامج وأجزاءه لأي مكان في الذاكرة فقط بتغيرر عنوان بداية الـ segment…
3. في معالجات Intel الـ 16 بت أو عندما يكون المعالج في وضع الـ real-mode في بداية تشغيله هناك ستة segment registers وهي cs/ds/ss/es/fs/gs.
كون المعالج 16 بت، فأقصى حجم ذاكرة هو 64KB، لكن إضافة الـ segmentation يزيد حجم الذاكرة لـ 1MB، لكن هذه كانت فائدة إضافية وليست فقط الهدف…
4.عندما يتم تفعيل الـ protected-mode ويصبح المعالج 32 بت، بدلاً من أن تخزن الـ segment registers عناوين مباشرة، أصبحت تخزن indexes ويتغير اسمها إلى segment selector registers، ولغرض الحماية لم يعد المُستخدم في الـ ring-3 قادر على تغيير قيمها كما هو الحال في الـ real-mode…
5. الـ segment selector حجمه كما كان، 16 بت، أول بتين تحدد الصلاحية، قيمته 0b11 في الـ user-mode أو 0b00 في الـ kernel-mode (هناك تفاصيل إضافية لكنها لا تهم فلا تستخدمها أنظمة التشغيل الحالية).
البت الثالث لو كان 0 فإن الـ index يشير لـ GDT ولو كان 1 فإنه LDT، ستجده دائماً 0…
6. الـ 14 بت الباقية تمثل الـ index في الـ GDT (أو الـ LDT لو كان البت الثالث 1).
الـ GDT و الـ LDT هما structures فيها معلومات أهمها نوع الـ selector هل هو GDT أم LDT، وصلاحيات الوصول له (ring-0/ring-3) وعنوان الـ based address و الـ limit التي تمثل حجم الـ segment…
7. أنظمة التشغيل حالياً لا تستخدم الـ segmentation وتستخدم بدلها الـ paging لإدارة الذاكرة، لكن في x86 الـ segmentation إجباري بينما paging اختياري.
لذا يتم إنشاء أربعة segments، منها 2 للـ ring-0 أحدها data والآخر code، و 2 آخران للـ ring-3، كلها تبدأ من 0 وبحجم الذاكرة (4GB)…
8. هكذا يصبح الـ segmentation كأنه غير موجود، ويتم تفعيل الـ paging الأكثر مرونة.
في x64 والمعالج في الـ long-mode لا يوجد عملياً segmentation فقط paging، حيث يفترض المعالج الـ segment base address دائماً 0 لكل الـ selectors ويفترض أن حجمها حجم الذاكرة، لكن يتم استثناء gs و fs…
9. أغلب أنظمة التشغيل تستخدم الـ gs و fs لتخزين بعض المعلومات كي تتجنب استخدام الـ system calls (البطيئة) أو استخدام الـ general registers (القليلة) للحصول عليها.
مثلاً يخزن Windows x64 في gs رقم index لمدخل في جدول الـ GDT يشير الـ base address فيه لعنوان الـ PEB في الذاكرة…
10. الـ PEB خاصة بـ Windows وفيها معلومات عن الـ thread الحالية: en.wikipedia.org
لما تكتب شيء مثل mov rax, gs:[0x48]، سيقرأ المعالج الـ GDT index من gs ليحصل على الـ base address والذي خزن فيه Windows عنوان الـ PEB في الذاكرة، ثم سيقرأ الـ field عند الـ offset رقم 0x48…
11. في Windows x86 و Linux يتم استخدام gs و fs لنفس الغرض، وهو تفادي استخدام الـ registers المحدودة العدد في x86/x64، لهذا لم يتم تعطيل gs و fs في x64.
تختار أنظمة التشغيل عادةً أحد registers العادية لو كانت architecture المعالج فيها registers كثيرة.

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