لغة C و برمجة النظم Systems Programming
لغة C و برمجة النظم Systems Programming
برمجة النظم ،Systems Programmingتشير إلى عملية الوصول إلى عتاد الحاسوب )البنية الصلب(
و العتماد عليها ،و فائدة برمجة النظم كبيرة في مجال برمجة أنظمة التشغيل ،بل هي الطريق الوحيدة
لعمل نظام تشغيل.
1.2المعالج :Processor
المعالج هو وحدة تعالج البيانات من وحدات أخرى مثل :وحدة الدخال ،وحدة الخراج ،و وحدات التصال
و التشبيك ،ثم تظهر تلك البيانات بشكل آخر أو تقوم بتخزينها.
سوف نتطرق إلى الجزء 16بت من المعالجات الخاصة بشركة Intelو التي تدعى بـعائلة . x86
تحتوي المعالجات على مسجلت Registersمختلفة لكل منها عملها ،و هي أربع أقسام و هي:
أي بما يسمى بـ ،BIOSو هو نظام موجود بدائرة ذاكرة القراءة فقط ،(ROM (Read Only Memory
يتم تشغيله عند تشغيل الحاسوب مباشرة ،و ينتهي عمله عند إقلع نظام التشغيل ،و يحتوي على
مقاطع تحتوي على دوال ،كل مقطع مخصص لدوال معنية في نفس المجال ،مثال على ذلك ،المقطع
(h = Hexadecimal) 10يقوم بالوصول إلى بطاقة الفيديو و استعمال دوالها.
1.4مقاطعات المعالج:
عدد مقاطعات المعالج هي ،256كل مقطع منها لدية دوال في نفس المجال ،يمكن ذكر بعض المقاطع
كما يلي:
المقطع ،10hو هو خاص بدوال بطاقة الفيديو.
المقطع ،11hو هو خاص بدوال بها معلومات حول خصائص الحاسوب.
المقطع ،12hهو خاص بدوال ذاكرة الوصول العشوائية .RAM
المقطع ،13hبه دوال حول القرص المرن و القرص الصلب.
المقطع ،14hو خاص بدوال المنفذ التسلسلي .Series
المقطع ،15hخاص بدوال شريط الكاسيت.
المقطع ،16hخاص بدوال لوحة المفاتيح .Keyboard
المقطع ،17hخاص بدوال منفذ التوازي للطابعة.
المقطع ،1Ahخاص بدوال الوقت و التاريخ.
المقطع ،33hو هو خاص بدوال الفأرة .Mouse
هنا سنتعرف على بعض التطبيقات في برمجة النظم،إذا أردنا عمل برنامج بدون ضم أي ملف من
الملفات الرئيسية فذلك ممكن ،و لكنه سيصعب علينا الطريق ،و أيضا سنحتاج إلى معرفة واسعة في
لغة التجميع كي نقوم بتفادي ضم الملفات الرئيسية .سأعطي مثال بسيط حول طريقة برمجة دوالك
الخاص باستخدام لغة Cبدون استعمال أي دوال أخرى .أول نحتاج إلى دالة تقوم بمسح الشاشة ،و
أخرى تقوم بإنتظار المستخدم أن يقوم بالضغط على زر ما من أزرار لوحة المفاتيح ،في دالة مسح
الشاشة سنستعمل مقطع من مقاطع نظام BIOSو هو المقطع 10hو الخاص ببطاقة الفيديو ،و
سنستعمل الدالة 3من هذا المقطع و نضعها في المسجل ،AXأما الدالة التي تنتظر المستخدم أن
يضغط على زر نستعمل المقاطعة 16hو التي بها دوال خاصة بلوحة المفاتيح ،و هنا سنستعمل الدالة
10من دوال لوحة المفاتيح .و سيكون البرنامج على الشكل التالي:
كود:
;)void clrscr(void
;)void getch(void
{)main(void
;)(clrscr
;)(getch
}
{)void clrscr(void
asm mov ax, 3
asm int 10h
}
{)void getch(void
asm mov ax, 10
asm int 16h
}
يحتوي المر movعلى وسيطين ،الول هو لسم مسجل ،و الثاني هو لقيمة التي سيتم وضعها في
المسجل .أما intفهي نستعملها في استدعاء المقاطع ،و هي مختصرة من .interruptionفي حالة
أنك تستعمل المترجم Turbo Cفيجب عليك ترجمة هذه البرنامج باستخدام المر tccمن الـ .DOS
و بهذه الطريقة يمكن الوصول إلى أي مكان من أمكان المعالج ،و استخدام مقاطعة نظام BIOSو
دواله ،و لكن هذه طريقة أمرها طويل ،و من البرنامج السابق لن نلحظ شيء ،لن تلك الدوال بسيطة
و ل تحتاج إلى إرجاع قيمة أو استعمال بها مؤشرات أو سلسل حرفية ،فمثل إذا أردنا برمجة دالة
مكافئة لدالة printfباستخدام الطريقة السابقة فسيكون العمل عليها غير مجدي ،لذا سنستعمل
المترجمين Turbo Cو ،Quick Cلن بهما دالة تتعامل مع المقاطع بطريقة كفوءة ،و أيضا لن نحتاج
إلى استعمال أوامر لغة التجميع مما يجعل البرمجة أكثر سهولة.
اسم الدالة هو ،int86و هي من دوال الملف الرأسي ،dos.hتحتوي على ثلثة وسائط ،و نموذج هذه
الدالة مكتوب بهذه الطريقة:
كود:
;)int int86(int intno, union REGS *inregs, union REGS *outregs
بالنسبة للوسيط الول فهو سيحمل قيمة المقطع المراد استعماله ،أما الوسيط الثاني و الثالث فهما
لبنية من نوع unionو التي تحمل القيمة التي سيتم استعمالها مع المقاطعة .و البنية REGSتحتوي
على بنيتين ،البنية xو التي تحتوي على أسماء مسجلت المعالج ذات الحجم 16بت أي 2بايت أي
كلمة ،و تلك المسجلت هي ،AX, BX, CX, DX, SI, DIو cflagو ،flagو هي معرفة بالشكل التالي:
كود:
{ struct WORDREGS
unsigned int ;ax, bx, cx, dx, si, di, cflag, flags
;}
أما البنية الثانية فهي ،hو هي تحمل أسماء مسجلت المعالج ذات الحجم 8بت أي 1بايت ،و التي هي
،AH, AL, BH, BL, CH, CL, DH, DLو البنية معرفة بالشكل التالي:
كود:
{ struct BYTEREGS
;unsigned char al, ah, bl, bh, cl, ch, dl, dh
;}
أما البنية REGSفهي معرفة بالشكل التالي:
كود:
union REGS {
;struct WORDREGS x
;struct BYTEREGS h
;}
و إذا أردنا كتابة المثال السابق باستخدام هذه الدالة فسيكون البرنامج كتالي:
كود:
>#include<dos.h
;)void clrscr(void
;)void getch(void
{)main(void
;)(clrscr
;)(getch
}
{)void clrscr(void
;union REGS regs
;regs.x.ax = 0x0003
;)int86(0x0010, ®s, ®s
}
{)void getch(void
;union REGS regs
;regs.x.ax = 0x0010
;)int86(0x0016, ®s, ®s
}
في دالة مسح الشاشة استعملنا xمن البنية regsلننا سنستعمل مسجل بحجم 16بت و الذي هو ،ax
أما الرقم x0003 0فهو بالنظام ستعشري لدالة مسح الشاشة .و في الوسيط الول من الدالة int86
استعملنا الرقم x0010 0و الذي هو رقم مقطع دوال الفيديو ،أما الوسيط الثاني فهو للبنية التي سيتم
أخذ قيمها و تطبيقها على رقم المقاطعة ،و تأخيرا الوسيط الثالث و الذي يقوم بوضع نتائج العمليات في
نفس البنية ،و أيضا توجد طريقة أخرى توضح فائدة الوسيط الثالث و هي تكون على الشكل التالي:
كود:
{)void clrscr(void
;union REGS inregs, outregs
;inregs.x.ax = 0x0003
;)int86(0x0010, &inregs, &outregs
}
توجد دالة أخرى مشابه لدابة int86و هي ،int86xو هي مكافئة للسابقة إل ان لها وسيط إضافي
لبنية اخرى ،و اسم تلك البنية هو SREGSو هي معرفة بالشكل التالي:
كود:
struct SREGS {
unsigned int ;es
unsigned int ;cs
unsigned int ;ss
unsigned int ;ds
;}
و نستعمل هذه الدالة في حالة حاجتنا إلى استخدام مسجلت المقاطع .Segment Registers
بالنسبة لرقم 0x0021فهو لمقطع دوال نظام ،DOSو هذا مثال لطريقة استخدام هذه الدالة:
كود:
>#include<dos.h
;)void putch(char ch
;)void clrscr(void
;)void getch(void
{)main(void
;)(clrscr
;)'putch('H
;)'putch('e
;)'putch('l
;)'putch('l
;)'putch('o
putch(10); /*New Line (ASCII)*/
putch(13); /*Return Carriage (ASCII)*/
;)(getch
}
{)void clrscr(void
;union REGS inregs, outregs
;inregs.x.ax = 0x0003
;)int86(0x0010, &inregs, &outregs
}
{)void getch(void
;union REGS regs
;regs.x.ax = 0x0010
;)int86(0x0016, ®s, ®s
}
الدالة 0x0002تقوم بطبع حرف على الشاشة ،و هي تحتوي على وسيط واحد و هو للحرف الذي
سيتم طبعه ،حيث يتم وضع الحرف في المسجل .dl
الن سأعطي بعض المثلة المتفرقة ،و التي سنرجع إلى شرحها التفصيلي في وقتها ،أول نبدأ بدالة
تقوم بتحريك مؤشر الكتابة إلى مكان يقوم بتحديده المبرمج ،سنستعمل هنا دوال الفيديو و التي هي
موجودة في المقطع ،10hو سيكون اسم الدالة هو ،gotoxyو رقم الدالة في المقطع 10hهو
،0x02و لها ثلثة وسائط و هي :وسيط لرقم صفحة الشاشة في المسجل bhو التي تكون غالبا ،0و
وسيط لمكان المؤشر في التجاه xو التي تكون في المسجل ،dlو أخيرا الوسيط الثالثة و هو لمكان
المؤشر في التجاه yو الذي يكون في المسجل ،dhأما رقم الدالة فسيكون في المسجل ،ahالدالة:
كود:
{)void gotoxy(int x, int y
;union REGS inregs, outregs
;inregs.h.ah = 0x02
;inregs.h.bh = 0x00
;inregs.h.dh = y
;inregs.h.dl = x
;)int86(0x0010, &inregs, &outregs
}
و يمكن أيضا عمل عكس هذه الدالة ،حيث تقوم بأخذ قيم لموقع المؤشر ،و ذالك بالعتماد على الدالة
0x03من نفس المقطع ،حيث تكون الدالة كتالي:
كود:
{)void getxy(int *x, int *y
;union REGS inregs, outregs
;inregs.h.ah = 0x03
;inregs.h.bh = 0x00
;)int86(0x0010, &inregs, &outregs
;*x = outregs.h.dl
;*y = outregs.h.dh
}
و من الدالة gotoxyيمكننا عمل دالة أخرى تقوم بمسح الشاشة و تكون مكافئة بدالة ،clrscrو هي
على الشكل التالي:
كود:
{)void clrscr(void
;int i
)for(i=0;i<25;i++
;)"printf("\n
;)gotoxy(0, 0
}
الن نذهب إلى كيفية عمل دالة تقوم بطباعة حرف على الشاشة ،مع إمكانيات التحكم في لون هذا
الحرف ،و هنا سنستعمل الدالة 0x09من المقطع ،10hو هي تحتوي على أربعة وسائط ،الوسيط
الول هو الحرف المراد طبعه و الذي يكون في المسجل ،alو الوسيط الثاني لصفحة الشاشة و التي
تكون دائما 0x00في المسجل ،bhو الوسيط الثالث للون الحرف و الذي يكون في المسجل ،blو
أخير الوسيط الرابع و الذي هو عدد الحرف المراد طبعه و يكون في المسجل ،cxو الدالة تكون على
الشكل التالي:
كود:
{)void putc(char ch, int color
;union REGS inregs, outregs
;inregs.h.ah = 0x09
;inregs.h.al = ch
;inregs.h.bh = 0x00
;inregs.h.bl = color
;inregs.x.cx = 0x0001
;)int86(0x0010, &inregs, &outregs
}
و من هذه الدالة يمكننا عمل دالة تقوم بطباعة سلسلة حرفية ،و تكون على الشكل التالي:
كود:
{)void puts(char *str, int color
;union REGS regs
;int getx
;regs.h.ah = 0x03
;regs.h.bh = 0x00
;)int86(0x0010, ®s, ®s
;getx = regs.h.dl
{)while(*str
;)putc(*str++, color
;regs.h.ah = 0x02
;regs.h.bh = 0x00
;regs.h.dl = ++getx
;)int86(0x0010, ®s, ®s
}
}
إل هنا نتوقف ،و هكذا نكون أقد أخذنا فكرة عامة عن برمجة النظم ،و في الدروس القادمة سنقوم
بتخصيص كل منها مجاله الخاص في كل من :لوحة المفاتيح ،الفأرة ،المقود ،الوصول إلى منفذ الطابعة،
الوصول إلى منفذ التسلسلي ،Seriesالقرص الصلب و المرن ،و قارئ القراص المضغوطة ،الوصول
إلى بطاقة الفيديو ... ،و أخيرا مبادئ في برمجة أنظمة التشغيل .و هذا كله في حالة استمرار هذه
السلسلة .و السلم عليكم...
التوقيع :
التعلم ليس بالمر الصعب ولكن ركز وتلقى المعلومة جيدًا. .1
الحب والخلص سبب نهوض الكثير فلنحب بعضنا ونخلص لبعضنا البعض. .2