طباعة هذه الصفحة
كتبه المجمع NASM 5718
الدرس 13: الدوال الدرس 13: الدوال
قيم الموضوع
(1 تصويت)
 
 عندما تقرر برمجة مشروع كبير، فلابد لك من استعمال الدوال لتسهيل العمليات عليك ومن أجل تقسيم المشروع إلى مشاريع أصغر تقوم بحل كل واحد منها على حدى. لنرى إذن كيف يمكن استعمال الدوال في المجمع.

1. مقدمة

إذا كنت قد درست فإنك تعرف ما معنى الدوال.

إذا كنت قد درست Pascal  فإنك تعرف ما معنى الدوال الرجعية واللارجعية.

إذا كنت قد درست BASIC  فإنك تعرف ما معنى كلمة SUB.

إذا كنت تعرف الخوارزم فإنك تعرف ما معنى الدوال.

تعريف عام : الدوال عبارة عن شُفَيرات أو شفرات تابعة للمشروع أو للشفرة الرئيسية.

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

ميزة الدوال : من خلال دراستنا للمجمع رأينا أن الخزانات تعتبر بمثابة المتغيرات، ونظرا لأهميتها فمن الواجب عند إنجازنا لمشروع معين يجب الأخذ بعين الاعتبار إرجاع  قيم الخزانات (التي كانت تحتويها منذ البداية) إليها، حتى لا نمس حركيتها في النظام. وهنا تبرز أهمية أدوات المكدس PUSH و POP وغيرهما.


2. الدالة

2.1 الكتابة العامة

الكتابة الخوارزمية الكتابة في المجمع
 اسم_الدالة(المداخيل...) : النوع
    .....
 نهاية_الدالة

 <المداخيل>
 <اسم_الدالة>:
    .....
 ret

أمثلة :

مثال 1 : أنشئ دالة تقوم باستدعاء النظام الهندسي (الدالة 13h للقاطعة 10h)

modevga:
  
movax , 13h
  
int   10h
ret

مثال 2 : أنشئ دالة تقوم باستدعاء النظام النصي (الدالة 03h للقاطعة 10h)

modetext:
  
movax , 03h
  
int
  10h
ret

2.2 استدعاء الدالة

لاستدعاء الدالة داخل المشروع أو الشفرة نستعمل الأداة CALL، ونكتب مثلا:

call modetext

2.3 أين نضع الدوال

يمكن وضع الدوال في بداية المشروع أو في نهايته أو في ملف آخر نقوم باستدعائه.

مثال كامل 1 : نضع الدوال في آخر الشفرة

            ;NASM-IDE ASM Assistant Assembler Project File
[BITS 16]    ;Set code generation to 16 bit mode
[ORG 0x0100] ;Set code start address to 0100h

[SEGMENT .text] ;Main code segment
call modevga

mov ax,0A000h 
mov es,ax

mov dl,205        ;نرسم نقيطة ذات اللون 205
mov [es:25700],dl

call getch        ; وانتظار الضغط على مفتاح

call modetext     ; الرجوع إلى النظام النصي

mov ax,4c00h
;هذه الدالة ضرورية لإنهاء الشفرة أو المشروع
int 21h
;---هنا يمكن أن نضع الدوال بعد دالة الإنهاء مباشرة-----------
modetext:
  mov ax,3
  int 10h
ret

modevga:
  mov ax,13h
  int 10h
ret

getch:
  mov ah,0 ;xor ah,ah
  int 16h
ret

;--------------------------------------------------------
[SEGMENT .data] ;التعريفات المهيئة

[SEGMENT .bss] ;التعريفات غير المهيئة

مثال كامل 2 : نضع الدوال في أول الشفرة

          ;NASM-IDE ASM Assistant Assembler Project File
[BITS 16]    ;Set code generation to 16 bit mode
[ORG 0x0100] ;Set code start address to 0100h

[SEGMENT .text] ;Main code segment

JMP albidaya ; اقفز إلى بداية الشفرة
;---هنا يمكن أن نضع الدوال في أول الشفرة-----------
modetext:
  mov ax,3
  int 10h
ret

modevga:
  mov ax,13h
  int 10h
ret

getch:
  mov ah,0 ;xor ah,ah
  int 16h
ret

;--------------------------------------------------------

albidaya : ;بداية الشفرة
call modevga

mov ax,0A000h 
mov es,ax

mov dl,205        ;نرسم نقيطة ذات اللون 205
mov [es:25700],dl

call getch        ; وانتظار الضغط على مفتاح

call modetext     ; الرجوع إلى النظام النصي

mov ax,4c00h
;هذه الدالة ضرورية لإنهاء الشفرة أو المشروع
int 21h

[SEGMENT .data] ;التعريفات المهيئة

[SEGMENT .bss] ;التعريفات غير المهيئة

مثال كامل 3 : نضع الدوال في ملف آخر ثم نستدعيه بالأداة include%

ننشئ ملفا يحمل اسما معينا مثلا  kiki.inc  ونكتب فيه جميع الدوال التي نريدها. قم بحفظ الملف في المجلد الذي يحمل الاسم INCLUDE.

;Ismo almilaf howa: kiki.inc
modetext:
  mov ax,3
  int 10h
ret

modevga:
  mov ax,13h
  int 10h
ret

getch:
  mov ah,0 ;xor ah,ah
  int 16h
ret

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

     ;.text و .bss و .data ملاحظة : يمكنك تغير ترتيب القطع
[BITS 16]   
[ORG 0x0100]
 

[SEGMENT .data]
%include "kiki.inc" ;يمكنك أن تستدعي الملف هنا 

[SEGMENT .bss]

[SEGMENT .text]

call modevga

mov ax,0A000h 
mov es,ax

mov dl,205       
;نرسم نقيطة ذات اللون 205
mov [es:25700],dl

call getch        ; وانتظار الضغط على مفتاح

call modetext     ; الرجوع إلى النظام النصي

mov ax,4c00h
;هذه الدالة ضرورية لإنهاء الشفرة أو المشروع
int 21h

 


3. الدالة الكاملة (أو النظيفة)


مثال 1 :
أنشئ دالة تقوم باستدعاء النظام الهندسي (الدالة 13h للقاطعة 10h)

modevga:
  
movax , 13h
  
int   10h
ret

نلاحظ أننا إذا استدعينا الدالة modevga  فإن الخزان AX سيتغير محتواه، لأنها ستستعمله بطبيعة الحال.

ولتفادي هذا المشكل نستعمل أدوات المكدس للحفاظ على محتواه الأصلي أي باستعمال push  و pop .

نكتب في النهاية :(هذا الشكل يسمى بالدالة الكاملة أو النظيفة)

modevga:
  
pushax          ;نحفظ قيمته الأصلية
  
movax , 13h  ;يتغير محتواه
  
int   10h
  
popax           ;نسترجع قيمته الأصلية
ret

مثال 2 : حالة دالة تستعمل خزانين أو ثلاث

دالة غير كاملة دالة كاملة

 gotoxy:
   
mov ax,0200h
    mov bh,0
    mov dx,1010h
    int 10h

 ret

 gotoxy:
   
push ax
   
push bx
  
 push dx
  
 mov ax,0200h
    mov bh,0
    mov dx,1010h
    int 10h

   
pop dx
   
pop bx
   
pop ax
 ret

مثال 3 : حالة دالة تستعمل كثير من الخزانات

في هذه الحالة لا نستعمل push و pop  مكررة بعدد الخزانات، ولكن نستعمل pusha و popa لتفادي ذلك.

دالة غير كاملة دالة كاملة

gotoxy:
  
mov ax,0200h
   mov bh,0
   mov dx,1010h
   add cx,dx
   mov dx,bx
   int 10h

ret

gotoxy:
  
pusha
  
mov ax,0200h
   mov bh,0
   mov dx,1010h
   add cx,dx
   mov dx,bx
   int 10h

  
popa
ret

 


4. متغيرات الدالة

4.1 الطريقة العادية أو المرور عن طريق الخزان

مسألة: أنجز دالة تمكن من إظهار أي حرف يريده المستعمل.

الحل : الدالة 0Eh للقاطعة 10h تمكن من إظهار حرف على الشاشة.

الطريقة العادية  لكن يمكن أن ننشئ دالة ثم نستدعيها متى نريد نستعمل إذا هذين السطرين عوض 3 سطور كلما احتجنا إلى ذلك

 mov ah,0eh
 mov al,<الحرف>
 int 10h

 putchar :
   push ax
   mov ah,0eh
   int 10h
   pop ax
 ret

 mov al,<الحرف>
 call  
putchar

في هذا المثال نلاحظ أن محدد هذه الدالة هو al الذي نضع فيه الحرف المراد إظهاره.

ملاحظة : قد تتطلب الدالة أكثر من محدد واحد، في هذه الحالة نضع كل الخزانات التي تتغير باستمرار قبل أن نستدعي الدالة.

 

4.2 استعمال قيمة المتغير

مسألة: أنجز دالة تمكن من حساب متوسط  متغيرين N1 و N2 وضع النتيجة في المتغير res.

الدالة moyenne استعمالها داخل المشروع أو الشفرة

 moyenne :
   add ax,bx
   shr ax,1
 ret

 mov ax,[N1]
 mov bx,[N2]
 call  
moyenne 
 mov [res],ax

 

4.3 استعمال عنوان المتغير

مسألة: أنجز دالة تمكن من حساب متوسط  متغيرين N1 و N2 وضع النتيجة في المتغير res.

(راجع الفقرة 9 التي تخص العنونة ولاحظ الفرق بين كلمة المحتوى والعنوان للمتغير)

نستعمل في هذه الحالة الخزانات المؤشرة أو القاعدة كـ SI و DI و ...

الدالة moyenne استعمالها داخل المشروع أو الشفرة

 moyenne :
   mov ax,[si]    ;N1 نأخذ محتوى
   add ax,[di]    ;ax=N1+N2
   shr ax,1         ;ax=(N1+N2)/2
   mov [bx],ax  ;res=(N1+N2)/2
 ret

 mov si,N1       ;N1 نأخذ عنوان
 mov di,N2       ;N2 نأخذ عنوان
 mov bx,res      ;res نأخذ عنوان
 call  
moyenne

 

4.4 المرور عن طريق المكدس

 طريقة Pascal

هذه الطريقة تخص دوال اللغة Pascal.

الشكل العام : لتكن x و y و z  ثلاث محددات لدالة معينة. لدينا إذن:

push X
push Y
push Z
call function

إذا كان المحدد X مثلا عبارة عن متغير نكتب push word [x] عوض push x لكن مع تحديد حجم التحويل قبل [x].

(راجع الفقرة 10 التي تخص المكدس).

نعتبر المثال التالي : لننشئ دالة تقوم بحساب متوسط متغيرين N1 و N2 ونضع النتيجة في المتغير res.

الدالة moyenne

الدالة moyenne داخل المشروع

moyenne:
  
push bp              ;4;  bp نحفظ قيمة      
  
mov bp,sp          ;5;  bp=sp
  
mov ax,[bp+4]   ;6;  ax=N2
  
add  ax,[bp+6]   ;7;  ax=N2+N1
  
shr   ax,1           ;8;  ax=(N2+N1)/2
  
mov [bp+6],ax  ;9;  [bp+6]=ax
  
pop bp               ;10; bp نسترجع قيمة
ret  2                   ;11

  .....
  
pushword [N1]    ;1
  
pushword [N2]    ;2   
  
call  moyenne      ;3
  
popword [res]     ;12
  ....
  ....

شرح مفصل :

  1. يجب أن تعرف أولا وقبل كل شيء أن كلمة ret تعني retour أي رجوع ، حيث أنك عندما تريد أن تستدعي دالة معينة يقوم المجمع بحفظ العنوان الذي وصل إليه عند تنفيذ المشروع في المكدس قبل أن يذهب لتنفيذ الدالة وذلك حتى يتسنى له استرجاع العنوان الذي تم تخزينه في المكدس ليواصل من خلاله تنفيذ المشروع.

  2. إن الأرقام من 1  إلى 12 الملونة بالوردي  تعني لنا المراحل التي يمر منها المكدس، وإليك إذن هذه المراحل:

المراحل من 1 إلى 5

المرحلة 9

المرحلة 10

المرحلة 11

المرحلة 12

  N1 1
  N2 2
  عنوان IP للرجوع  3
SP و BP  حفظ قيمة BP 4 و5
     
 

(N2+N1)/2

  N2
  عنوان IP للرجوع 
SP  حفظ قيمة BP
   
 

(N2+N1)/2

  N2
 SP عنوان IP للرجوع 
   
   
SP

(N2+N1)/2

   
 

 

   
   
 

 

   
 

 

   
   
الحالة البدئية بعد المرور من المراحل 6 إلى 8 التي تعني بعض المعالجات فقط نقوم بحفظ النتيجة خلال المرحلة 9 في الخانة الأولى للمكدس التي كانت تحتوي على القيمة N1 في هذه المرحلة نسترجع القيمة الأصلية لـ BP الذي استعملناه للدخول وتغيير محتوى المكدس. ret  تعني الرجوع أي أن IP يأخذ العنوان الذي سيبدأ المجمع بمواصلة تنفيذ المشروع، أما 2 فتعني استخراج خانة واحدة (ثمنين)  بعد IP وطرحها جانبا (بمعنى أدق طرح الخانة التي تحمل N2 خارجا) في هذه المرحلة يأخذ المتغير res النتيجة التي بقيت في المكدس.

 لو لاحظت جيدا لرأيت أن الدالة moyenne غير كاملة أو غير نظيفة، لأننا استعملنا الخزان AX دون أن نحفظ قيمته الأصلية، وبالتالي ستصبح الدالة moyenne على الشكل التالي :(دالة كاملة)

moyenne:
  
push bp              ;  bp نحفظ قيمة      
  
mov bp,sp          ;  bp=sp
  push ax              ;  ax نحفظ قيمة      
  mov ax,[bp+6]   ;  ax=N2
  
add  ax,[bp+8]   ;  ax=N2+N1
  
shr   ax,1           ;  ax=(N2+N1)/2
  
mov [bp+8],ax  ;  [bp+6]=ax
  pop ax               ; ax نسترجع قيمة
  pop bp               ; bp نسترجع قيمة
ret  2
                  

 

 طريقة C

هذه الطريقة تخص دوال اللغة C.

الشكل العام : لتكن x و y و z  ثلاث محددات لدالة معينة. لدينا إذن:

push X
push Y
push Z
call function
<إفراغ المكدس>

طريقة C شبيهة إلى حد ما لطريقة Pascal إلا أن هنا فرق في إفراغ المكدس، حيث نقوم بتفريغه في نهاية الدالة أي مع ret مباشرة (مثلا ret 2) إلا أن طريقة C تفرغه بعد الخروج من الدالة مباشرة.

لنأخذ المثال السابق ونلاحظ الفرق:

الدالة moyenne

الدالة moyenne داخل المشروع

moyenne:
  
push bp              ;4;  bp نحفظ قيمة      
  
mov bp,sp          ;5;  bp=sp
  push ax              ;  ax نحفظ قيمة  
  
mov ax,[bp+6]   ;6;  ax=N2
  
add  ax,[bp+8]   ;7;  ax=N2+N1
  
shr   ax,1           ;8;  ax=(N2+N1)/2
  
mov [bp+8],ax  ;9;  [bp+6]=ax
  pop ax               ; ax نسترجع قيمة
  
pop bp               ;10; bp نسترجع قيمة
ret                       ;11

  .....
  
pushword [N1]    ;1
  
pushword [N2]    ;2   
  
call  moyenne      ;3   
  
add sp,2      ;12
  
popword [res]     ;13
  ....
  ....


5. تفصيل مهمة


قد لا تستوعب لماذا كتبنا ret 2 في طريقة Pascal أو add sp,2 في طريقة C.

أولا وقبل كل شيء : يجب أن تعرف أن تمارين الفقرة القادمة ' فقرة الجداول والمتسلسلات الحرفية' مليئة جدا بالدوال، ولذلك يجب أن تركز جيدا في هذه الفقرة على مبدئها.


5.1 المكدس

لو رجعنا إلى فقرة المكدس لرئينا أن كل خانة في المكدس حجمها هو : ثمنين  ( تذكر هذا جيدا )

وكذلك عند تعاملنا مع خانات المكدس يمكننا استعمال الخزان المؤشر bp الذي يأخذ قيمة خزان المكدس sp حتى يتسنى لنا أن نعالج المعطيات الموجودة داخل خانات المكدس.


5.2 إنشاء الدوال

لإنشاء دالة معينة لدينا عدة طرق، والطريقة الآمنة هي أن تنجز دالة نظيفة وكاملة،

لماذا يا ترى ؟

سؤال وجيه جدا : من خلال تجربتي الخاصة كنت لا أكثرت أن أنشئ دالة نظيفة أو لا، لكن عندما وضعت هذه الدوال في مكتبة ثم استدعيها كلما احتجت إليها كانت تقع لي أخطاء بليغة جدا ، هذه الأخطاء ليس في الشفرة أي لا يكتشفها المجمع، لكني اكتشفت بنفسي أن استعمالي لبعض الخزانات التي أحفظ فيها قيما معينة يتم تغييرها من طرف الدوال غير النظيفة ==> فقمت حينها بإعادة جميع الدوال.


5.3 الأداة
ret

كما قلنا سابقا أن الأداة ret تعني الرجوع.

غالبا ما نقوم بإدخال القيم ذات الحجم ثمنين إلى المكدس.

 قيمة ذات الحجم ثمنين

عند إدخالنا قيمة واحدة ذات الحجم ثمنين : نكتب في نهاية الدالة ret 2 حيث (ret تعني إرجاع قيمة IP التي تم تخزنها نلقائيا في المكدس و 2 تعني طرح خانة ذات الحجم ثمنين )

أمثلة :

مثال 1

function1:
;....
ret 2

push ax
call function1

مثال 2

function2:
;....
ret 2

push word adress
call function2

مثال 3

function3:
;....
ret 2

push word [valeur]
call function3

 قيمتين أو أكثر ذات الحجم ثمنين

عند إدخالنا لـ N  قيمة ذات الحجم ثمنين : نكتب في نهاية الدالة ret 2N حيث (ret تعني إرجاع قيمة IP التي تم تخزنها نلقائيا في المكدس و 2N تعني طرح N خانة ذات الحجم ثمنين )

أمثلة :

مثال 1

function1:
;....
ret 4

push ax
push bx
call function1

مثال 2

function2:
;....
ret 4

push word adress1
push word adress2
call function2

مثال 3

function3:
;....
ret 8

push word [valeur]
push word adress
push word [valeur2]
push dx
call function3

 انتبه جيدا:  قيمة أو أكثر ذات الحجم 4 أثمان

عند إدخالنا قيمة ذات الحجم 4 أثمان : نكتب في نهاية الدالة ret 4 حيث (ret تعني إرجاع قيمة IP التي تم تخزنها نلقائيا في المكدس و 4 تعني طرح  خانتين ذات الحجم ثمنين أو بمعنى آخر خانة ذات الحجم 4 أثمان )

أمثلة :

مثال 1

function1:
;....
ret 4

push eax
call function1

مثال 2

function2:
;....
ret 4

push dword [adress2]
call function2

مثال 3

function3:
;....
ret 12

push ax
push ebx
push dword [valeur2]
push word adress
call function3

 ملاحظة مهمة

كما رأينا أعلاه أننا نطرح جميع خانات المكدس التي تم ملئها من طرف القيم التي نود إدخالها.

سؤال : ماذا لو أردنا أن نحتفظ بالخانة الأخيرة التي نود أن نضع في قيمة أو نتيجة ما، حتى يأخذها متغير أو خزان آخر من خلال المشروع الذي سننجزه؟

الجواب : يكفي أن تطرح 2 من العدد الموجود أمام الأداة ret مباشرة.

مثال :

الدالة moyenne

الدالة moyenne داخل المشروع

توضيح

moyenne:
  
push bp              ;4;  bp نحفظ قيمة      
  
mov bp,sp          ;5;  bp=sp
  push ax              ;  ax نحفظ قيمة  
  
mov ax,[bp+6]   ;6;  ax=N2
  
add  ax,[bp+8]   ;7;  ax=N2+N1
  
shr   ax,1           ;8;  ax=(N2+N1)/2
  
mov [bp+8],ax  ;9;  [bp+6]=ax
  pop ax               ; ax نسترجع قيمة
  
pop bp               ;10; bp نسترجع قيمة
ret 2                      ;11

  .....
  
push word [N1]    ;1
  
push word [N2]    ;2   
  
call  moyenne      ;3   
  
pop word [res]     ;13
  ....
  ....

 كما نلاحظ أننا أدخلنا متغيرين اللذان هما   : N1 و N2 ،
إذا كان علينا أن نكتب في النهاية ret 4، 
لكننا كتبنا فقط ret 2 ، وذلك حتى إذا خرجنا من الدالة moyenne نود أن نضع النتيجة التي بقيت في آخر خانة بالمكس في المتغير res
حيث نكتب :   pop word [res]  

6. مساعدة

لم أكن أود أن أمنحك هذه الدالة التي تقوم بإظهار الأعداد على الشاشة لأنني كنت أودك أن تصل إلى الفقرة التالية "الجداول والمتسلسلات الحرفية" التي تحتوي على نصف تمارين المجمع حيث ستكون هذه التمارين على هذا المنوال، أي إنجاز دوال لإظهار الأعداد والجمل إلى آخره ...

المهم : لإظهار الأعداد على الشاشة يمكنك استعمال الدالة oktob16 الموجودة في المكتبة entier.inc التي وضعتها في المجلد INCLUDE.

لإظهار أي عدد موجب من 0  إلى 65535 يجب وضعه في الخزان AX ثم استدعي الدالة oktob16 بالأمر call.

مثال للاستعمال :

مثال لجمع عددين

          
 [BITS 16]   
 [ORG 0x0100]

 [SEGMENT .data] ;Main code segment
 %include
'entier.inc'  ;استدعاء المكتبة

 [SEGMENT .text] ;Main code segment

 mov  bx,10
 mov  cx,20

 mov ax,bx
 call
oktob16

 mov ax,0E00h+'+'
 int 10h

 mov ax,cx
 call
oktob16

 mov ax,0E00h+'='
 int 10h

 add bx,cx

 mov ax,bx
 call
oktob16

 mov ah,0
 int 16h
 mov ax,4C00h
 int 21h

النتيجة على الشاشة

 10+20=30


تمارين تطبيقية


التمرين 13.1

أنجز شفرة تقوم بجمع عددين واستعمل:

  1. الطريقة العادية (المرور مباشرة)
  2. استعمال قيمة المتغير
  3. استعمال عنوان المتغير
  4. المرور عن طريق المكدس
    • طريقة Pascal
    • طريقة C

التمرين 13.2

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char C;
void main()
{
  C=getchar();
  puchar(C);
}

var  C: char;

begin
  C:=readkey;
  write(C);
end.

 


التمرين 13.3

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char ch[20]="Salamo 3alaikom";
void main()
{
   printf("%s",ch);
   getch();
}

var  ch: string[20];
begin
   ch:="Salamo 3alaikom";
   write(ch);
   readln;
end.

 


التمرين 13.4

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char ch[30]="Jomla men fadlek\n";
char ch1[30];
void main()
{
printf("%s",ch);
scanf("%s",ch1);
printf("%s",ch1);
getch();
}

var  ch : string[30];
       ch1: string[30];
begin
   ch:="Jomla men fadlek";
   writeln(ch);
   read(ch1);
   writeln(ch1);
   readln;
end.

 


التمرين 13.5

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char i;
void main()
{ for(i=0 ; i<10 ; i++) putchar('S');
 getch();
}

var  i : integer;
begin
   for i:=0 to 9 do  write('S');  
   readln;
end.

 


التمرين 13.6

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char C = '0';
int  i;
void main()
{ for(i=0 ; i<10 ; i++)
    {putchar(C);
     putchar(' ');           
     C++;            }
 getch();
}

var  i : integer;
       C: char;
begin
   for i:=0 to 9 do   
   begin
      write(C); write(' '); C:=C+1;
   end;
   readln;
end.




التمرين 13.7

أعد كتابة الشفرة التالية المكتوبة باللغة C أو المكتوبة باللغة Pascal في المجمع NASM باستعمال الطريقة التي تريدها.

في C في Pascal

char C;
void main()
{  do
    {C=getchar();  }      
     while(C!='n');
}

var  C: char;
begin   
   repeat
     C:=readkey;
   until (C='n');
end.




التمرين 13.8

أنجز دالة تقوم بإبدال محتوى متغيرين من نوع db يحملان حرفين.

استعمل دالة لقراءة حرفين من لوحة المفاتيح ووضعهما في المتغيرين (كـ ()getchar).

استعمل دالة لإظهار محتوى المتغيرين قبل وبعد الإبدال (كـ ()putchar).

استعمل كذلك دالة لإظهار جملة على الشاشة (كـ ()printf).

مثال :

Harfaine men fadlek :
N1 = A
N2 = B
Ba3da AL Ibdale :
N1 = B
N2 = A


التمرين 13.9

أنجز دالة تقوم بمعرفة طبيعة محتوى متغير من نوع db  يحمل حرفا، هل هو حرف كبير أو صغير أو رقم أو رمز.

استعمل دالة لقراءة حرف من لوحة المفاتيح ووضعه في المتغير.

استعمل كذلك دالة لإظهار جملة على الشاشة.

مثال :

Harf  men fadlek :  A
A  ---> harf  kabir

Harf  men fadlek :  5
5  ---> nombre

Harf  men fadlek :  !
!  --> symbole

Harf  men fadlek :  d
d  --> harf  sakhir


التمرين 13.10

أنجز دالة تقوم بتحويل الحرف الكبير إلى صغير وصغير إلى كبير. لكن بشرط أن تكون هذه الدالة تستعمل دالتين أُخريين إحداهما تقوم بتحويل الحرف الكبير إلى صغير والأخر بالعكس وكذلك دالة لإظهار حرف على الشاشة . لا تنس حالة أن يدخل المستعمل رمزا أو رقما

استعمل دالة لقراءة حرف من لوحة المفاتيح ووضعه في المتغير.

استعمل كذلك دالة لإظهار جملة على الشاشة.

مثال :

Harf  men fadlek :  A
Minusule ---> a

Harf  men fadlek :  f
Majuscule  ---> F

Harf  men fadlek :  ?
mostahil !!!!!

Harf  men fadlek :  6
mostahil !!!!!