السلام عليكم
هذه هي الصفحة المخصصة لـ16 كود أسمبلي 16 بت قمت بكتابتها عند تعلّمي للغة , نبدأ بالوصف ثم الكود:
======================================================
هذا هو كودي الأول ..
======================================================
الكود الثاني :
برنامج يأخذ محرفا من المستخدم .. فإن كان هو الرقم 1 يطبع one وإلا يطبع zero .. ( بمكن تطوير البرنامج لأي عدد من المحارف )
الكود التالي يقرأ حرف واحد من المستخدم .. ثم يقوم بطباعته .. وينتظر زرا آخر ليخرج
وهذا الكود مشابه للسابق .. ولكنه يدخل في حلقة : يطبع كل حرف يدخله المستخدم إلى أن ندخل enter
الكود الخامس .
البرنامج التالي يأخذ نصّا من المستخدم ويطبعه بشكل معكوس عن طريق تخزينه في المكدس ثم اخراجه :
_____________________إضافة : __________
لم أستطع منع نفسي من ذكر أن برنامج بلغة BrainF**k للقيام بنفس المهمة هو التالي :
الكود 6 : استخدام طريقة العنونة باستخدام الإزاحة[ disp[bx
الكود السابع :
الكود التالي يستخدم الإجراءات في عملية ضرب عددين كما أنه ينسّق العملية بشكل مرتب
لاحظ أنه يمكنك فهم الكود من أسماء الاستدعاءات calls دون عناء , ثم تعود إلى كل إجراء بشكل مستقل
مع العلم أنني استخدمت المكدّس لإعادة الناتج , ثم لأخذ الوسطاء في الإجراءات التالية
الكود الثامن . الهدف منه توضيح استخدام الخدمة 2 في المقاطعة 10 .. وهي خدمة نقل مؤشر الكتابة ... بدون مبالغة يمكن باستخدام هذه الخدمة رسم كل أحلامك على الشاشة .. الأكواد القادمة ستكون فيها رسومات جميلة
يا جماعة .. السلام عليكم
الكود التالي سيقوم برسم دائرة باستخدام تحريك المؤشر (مقاطعة الـBIOS رقم 10 الخدمة 2 )
الفكرة هنا هي في كيفية الاستفادة من db أي تحديد البيانات data التي سنحتاجها في الكود
10 - إجراء لطباعة القيمة العددية المحتواة في المسجل ah .. (وهو إجراء هام جدّاً لمن لا يعلم )
الكود الحادي عشر .. فتح ملف باستخدام الخدمة 3D ثم قراءة عشر بايتات منه باستخدام الخدمة 3F من مقاطعة الدوز رقم 21
الكود الثاني عشر
النسخة المحسنة من الكود 10 (ليست محسنة كثيراً)
البرنامج التالي يحوي إجراء Procedure لطباعة القيمة العشرية للمسجل AX (هام جداً )
يمكن للكسابى نسخ الـprocedure وإضافته لكودهم مباشرة .. وهو يترك cx دون تأثير ويستعمل ax,bx,dx
الفكرة بسيطة جداً القسمة 5 مرات على 10 وحفظ الباقي في المكدس ثم إخراجه وطباعته
الكود الثالث عشر : طباعة القيمة العشرية لمحتوى ax (الكود المحسّن)
يمكنك أخذ الإجراء مباشرة مع العلم أنه لا يؤثر على أي مسجّل بداخله , استعمله وأنت مرتاح
الكود الرابع عشر
يحتوي إجراء قراءة عدد (يجب أن يكون العدد أقل من 65536 )
الكود التالي يقرأ عدداً ثم يقوم بطباعته باستخدام الإجراء الذي كتبناه سابقاً
الكود الخامس عشر
الرابط الأصلي
الكود السادس عشر في الرابط التالي
انتهى نقل الأكواد, الأكواد السابقة كتبتها أثناء تعلمي للغة وهي الآن مرجع مفيد لمن يريد البدء بها
هذه هي الصفحة المخصصة لـ16 كود أسمبلي 16 بت قمت بكتابتها عند تعلّمي للغة , نبدأ بالوصف ثم الكود:
======================================================
هذا هو كودي الأول ..
برنامج يقوم بطباعة Hello World في حلقة لا نهائية .. وينتظر من المستخدم أن يضغط أي زر في كل دورة للحلقة
.model small .stack 100h .data msg db "Hello World!",10,13,"$" ;تعريف متغير يحوي العبارة المطلوبة ;10 ,13 هي محارف نهاية السطر ;$ محرف يدل على نهاية المتغيّر .code start: ;دليل يمكننا استعماله للعودة الى هذه النقطة mov ax,@data ;ax;نحفظ عنوان بداية قسم البيانات في mov ds,ax ;data segment;ds;في المسجّل ;ax;نحفظ العنوان الموجود في ; lea dx,msg ;<==>mov dx,offset msg;dx;وتعني حفظ عنوان المتحول في المسجل mov ah,9 ;dx;حفظ رقم المفاطعة الخاصة بطباعة النص الموجود عنوانه في int 21h ;ah;تنفيذ المقاطعة المحفوظة في mov ah,7;حفظ رقم المقاطعة التي تنتظر حرف من المستخدم int 21h ;ah;تنفيذ المقاطعة المحفوظة في jmp start ; قفز إلى الدليل أعلاه ;لن نصل إلى هنا أبدا mov ax,0c07h;حفظ رقم المقاطعة التي تنهي البرنامج int 21h ;ah;تنفيذ المقاطعة المحفوظة في end start; دليل نهاية الملف
======================================================
الكود الثاني :
برنامج يأخذ محرفا من المستخدم .. فإن كان هو الرقم 1 يطبع one وإلا يطبع zero .. ( بمكن تطوير البرنامج لأي عدد من المحارف )
.model small .stack 100h .data ;حفظ بعض البيانات zer db 9,"zero",10,"$" one db 9,"one",10,"$" ;10; هو رقم الآسكي لنهاية السطر ;9;tabهو رقم الآسكي ل; .code start: mov ax,@data mov ds,ax MOV AH,1;مقاطعة أخذ حرف من المستخدم INT 21h CMP AL,49;مقارنة الحرف المدخل مع قيمة الآسكي للرقم واحد JE ony;اذا كان ناتج المقارنة هو التساوي قم بعملية القفز ;سندخل هنا ان لم تنجح المقارنة lea dx,zer;نضع عنوان العبارة 'صفر' في مسجل البيانات jmp endy;ونقفز كي لا ننفذ السطر التالي ony: lea dx,one;نضع عنوان العبارة 'واحد' في مسجل البيانات endy: mov ah,9;مقاطعة طباعة النص الموجود عنوانه في مسجل البيانات int 21h jmp start;العودة لتكرار البرنامج ;لن نصل الى هنا ابدا mov ax,4c00h int 21h end start======================================================
الكود التالي يقرأ حرف واحد من المستخدم .. ثم يقوم بطباعته .. وينتظر زرا آخر ليخرج
.model small .stack 100h .data ;لا يوجد بيانات .code start: MOV AH,01;مقاطعة أخذ حرف من المستخدم INT 21h MOV DL,AL ;نقل الدخل الى المسجل المستخدم للخرج MOV AH,02; تخزين رقم المقاطعة الخاصة بطباعة حرف INT 21h MOV AH,07h; تخزين رقم المقاطعة الخاصة بإنهاء البرنامج INT 21h MOV AH,4Ch; تخزين رقم المقاطعة الخاصة بإنهاء البرنامج INT 21h end start======================================================
وهذا الكود مشابه للسابق .. ولكنه يدخل في حلقة : يطبع كل حرف يدخله المستخدم إلى أن ندخل enter
.model small .stack 100h .data ;لا يوجد بيانات .code start: MOV AH,01;مقاطعة أخذ حرف من المستخدم INT 21h CMP AL,10;مقارنة مع الآسكي المساوي للانتر JE endy;اذا تساوت اقفز الى النهاية CMP AL,13;مقارنة مع الآسكي المساوي للانتر JE endy;اذا تساوت اقفز الى النهاية ;سندخل هنا ان لم تنجح المقارنة MOV DL,AL ;نقل الدخل الى المسجل المستخدم للخرج MOV AH,02; تخزين رقم المقاطعة الخاصة بطباعة حرف INT 21h jmp start;العودة لتكرار البرنامج endy: MOV AH,4Ch; تخزين رقم المقاطعة الخاصة بإنهاء البرنامج INT 21h end start======================================================
الكود الخامس .
البرنامج التالي يأخذ نصّا من المستخدم ويطبعه بشكل معكوس عن طريق تخزينه في المكدس ثم اخراجه :
.model small .stack 100h .data .code mov ah,01;قيمة مقاطعة أخذ حرف من المستخدم mov cx,sp;نخزّن قيمة مؤشر المكدس في مسجل العداد start: int 21h;تنفيذ مقاطعة قراءة حرف من المستخدم cmp al,0Dh;هل هو نهاية السطر؟ jle end_ mov bl,al;نضغ في مسجل آخر لأن الدفع في المكدس يتطلب دفع مسجل 16 بت كاملة push bx ;نحفظ الدخل في المكدس jmp start end_: mov ah,02;تخزين قيمة مقاطعة طباعة حرف mov dl,0Ah;تخزين قيمة محرف نهاية السطر int 21h;تنفيذ مقاطعة طباعة الحرف والذي هو نهاية السطر print: cmp cx,sp;طالما لم يصبح مؤشر المكدس كقيمته قبل بدء التخزين je end__;اذا اصبح كقيمته القديمة اخرج pop dx;أخرج آخر حرف تم تخزينه int 21h;ونفذ مقاطعة الطباعة jmp print;وكرر العملية end__: mov ah,4ch;حفظ قيمة مقاطعة الانهاء int 21h; تنفيذ مقاطعة الإنهاء end
_____________________إضافة : __________
لم أستطع منع نفسي من ذكر أن برنامج بلغة BrainF**k للقيام بنفس المهمة هو التالي :
,+[->,+]<[.<]======================================================
الكود 6 : استخدام طريقة العنونة باستخدام الإزاحة[ disp[bx
;هذا الكود لتوضيح طريقة العنونة التالية ;displacement[bx] ;والتي تشبه الوصول إلى عنصر في مصفوفة .model small .stack 100h .data numbers db "ABCDEFGHIJKLMNOPQSTUVWXYZ$";نحفظ الحروف في مقطع البيانات .code mov ax,@data;\;نحفظ عنوان مقطع البيانات في مسجل مقطع البيانات mov ds,ax ;/ mov ax,0100h;\;مقاطعة قراءة حرف int 21h ;/ sub al,30h;تحول الحرف الى رقم mov ah,0 mov bx,ax ;نقل الناتج لمسجل القاعدة الذي يُستعمل في العنونة mov dl,numbers[bx];طريقة العنونة التي تقوم بالوصول للعنصر الذي عنوانه مجموع عنوان المتحول خارج الأقواس مع قيمة المسجل داخل الأقواس ;هو الذي تتم طباعة محتواه في مقاطعة طباعة الحرف;dl;المسجل ;ونضع فيه قيمة أحد الحروف المخزّنة والتي نصل اليها عن طريق عنوان المتحول مضافا اليه إزاحة mov ax,0200h;مقاطعة طباعة حرف int 21h mov ah,4ch;مقاطعة الخروج من البرنامج int 21h end======================================================
الكود السابع :
الكود التالي يستخدم الإجراءات في عملية ضرب عددين كما أنه ينسّق العملية بشكل مرتب
لاحظ أنه يمكنك فهم الكود من أسماء الاستدعاءات calls دون عناء , ثم تعود إلى كل إجراء بشكل مستقل
مع العلم أنني استخدمت المكدّس لإعادة الناتج , ثم لأخذ الوسطاء في الإجراءات التالية
;هذا الكود يوضّح عملية ضرب رقمين من الدخل وطباعتهما باستخدام العمليات ;Procedures ; ويمكنك قراءته وفهمه بسهولة بسبب القاعدة : فرّق تسد :) إنها السيطرة .model small .stack 100h .data .code;كل استدعاء يدل على وظيفته من اسمه call read_number call write_Multiplication_Sign call read_number call write_Equal_Sign call find_Result call print_Result call End_program read_number proc mov ax,0100h;نقوم بمقاطعة الدخل لحرف واحد int 21h sub al,30h;نحول الحرف الى رقم mov ah,00h;نصفّر الجزء العلوي من المسجل حتى يختفظ المسجّل بشكل كامل بالقيمة لنتمكن من دفعه للمكدّس pop bx;المكدّس يحتفظ بقيمة مؤشّر التعليمات لذلك يجب أن نحافظ عليه push ax;نصع نتيجة الإجراء في المكدّس push bx;ونعيد مؤشر التعليمات الى المكدّس ret;ونعود إلى التعليمة التي يشير لها مؤشر التعليمات read_number endp write_Multiplication_Sign proc mov ah,02h;تخزين قيمة مقاطعة الخرج لحرف واحد mov dl,2Ah;تخزين قيمة الآسكي لإشارة الجمع int 21h;طباعة الحرف المخزّن في المسجل السابق ret;العودة لحيث يؤشّر مؤشر التعليمات write_Multiplication_Sign endp write_Equal_Sign proc;نفس الإجراء السابق ولكن مع تغيير قيمة الآسكي لتطبع إشارة المساواة mov ah,02h mov dl,3Dh int 21h ret write_Equal_Sign endp find_Result proc pop cx;نحتفظ بمؤشر التعليمات pop ax;نأخذ الرقم الأول من المكدّس pop bx;نأخذ الرقم الثاني من المكدّس push cx;نرجع مؤشر التعليمات call multiply_Ax_Bx;نستعدي إجراء ضرب هذين المسجّلين ret find_Result endp multiply_Ax_Bx proc mul bx;سنستخدم الضرب العادي ret multiply_Ax_Bx endp print_Result proc;ax;يقوم بطباعة النتيجة الموجودة في mov cl,0Ah;نخزن الرقم 10 div cl;على 10;ax;نقسم ;حسب آلية عمل تعليمة القسمة;ah;وباقي القسمة في;al;ستخزّن نتيجة القسمة في ;al;والعشرات في;ah;الآحاد في; mov dx,ax; mov ah,02h;نضع قيمة تعليمة طباعة حرف add dh,30h;نحوّل الآحاد من رقم إلى حرف add dl,30h;نحول العشرات من رقم إلى حرف int 21h;نطبع العشرات mov dl,dh; int 21h;نطبع الآحاد ;dl;الطباعة تتم للقيمة الموجودة في ret print_Result endp End_Program proc;يقوم بتنفيذ مقاطعة الخروج من البرنامج mov ah,4Ch int 21h ret End_Program endp end======================================================
الكود الثامن . الهدف منه توضيح استخدام الخدمة 2 في المقاطعة 10 .. وهي خدمة نقل مؤشر الكتابة ... بدون مبالغة يمكن باستخدام هذه الخدمة رسم كل أحلامك على الشاشة .. الأكواد القادمة ستكون فيها رسومات جميلة
.model small .stack 100h .data .code mov ch,00 mov bl,41 label0: mov ah,2h;خدمة نقل المؤشر في المقاطعة 10 mov dh,ch;نحدد السطر mov dl,ch;نحدد العمود int 10h;تنفيذ المقاطعة الخاصة بنقل المؤشر mov ah,2h;خدمة طباعة حرف في المقاطعة 21 mov dl,41h;نضع أول حروف الأبجدية في المسجل add dl,ch;ونزيد قيمته حسب عداد الحلقة int 21h;تنفيذ المقاطعة الخاصة بطباعة الحرف inc ch;نزيد عداد المؤشر cmp ch,30;نقارن هل وصلنا إلى 30 jne label0;إن لم نصل نقفز عائدين إلى بداية العملية mov ah,1;خدمة أخذ حرف من المستخدم سنستخدمها للانتظار int 21h;تنفيذ مقاطعة أخذ الحرف من المستخدم mov ah,4ch;خدمة إنهاء البرنامج int 21h;تنفيذ خدمة الإنهاء end label0 end======================================================
يا جماعة .. السلام عليكم
الكود التالي سيقوم برسم دائرة باستخدام تحريك المؤشر (مقاطعة الـBIOS رقم 10 الخدمة 2 )
الفكرة هنا هي في كيفية الاستفادة من db أي تحديد البيانات data التي سنحتاجها في الكود
.model small .stack 100h .code jmp X ;فيما يلي أزواج النقاط أولا السينات ثم العينات _الصادات_تحدد الشكل المطلوب رسمه ;Home Made Circle By Mostafa36a2 db 1,10,1,11,1,12,1,13,1,14,1,15,1,16,1,17,1,18,1,19 db 1,20,2,8,2,9,2,10,2,20,2,21,2,22,3,7,3,8,3,22 db 3,23,4,5,4,6,4,24,4,25,5,4,5,5,5,25,5,26,6,4 db 6,26,7,3,7,27,8,2,8,3,8,27,8,28,9,2,9,28,10,1 db 10,2,10,28,10,29,11,1,11,29,12,1,12,29,13,1,13,29,14,1 db 14,29,15,1,15,29,15,30,16,1,16,29,17,1,17,29,18,1,18,29 db 19,1,19,29,20,1,20,2,20,28,20,29,21,2,21,28,22,2,22,3 db 22,27,22,28,23,3,23,27,24,4,24,26,25,4,25,5,25,25,25,26 db 26,5,26,6,26,24,26,25,27,7,27,8,27,22,27,23,28,8,28,9 db 28,10,28,20,28,21,28,22,29,10,29,11,29,12,29,13,29,14,29,15 db 29,16,29,17,29,18,29,19,29,20 y db 105;متحول يحفظ عدد النقاط X: mov bx,@code mov ds,bx mov ch,00 mov bx,03 dec bx label0: inc bx mov dh,[bx];نحدد السطر inc bx mov dl,[bx];نحدد العمود mov ah,2h;خدمة نقل المؤشر في المقاطعة 10 int 10h;تنفيذ المقاطعة الخاصة بنقل المؤشر mov ah,2h;خدمة طباعة حرف في المقاطعة 21 mov dl,4Dh;نضع أول حرف آسكي نريد طباعته int 21h;تنفيذ المقاطعة الخاصة بطباعة الحرف inc ch;نزيد عداد المؤشر cmp ch,y;قارن هل وصلنا لآخر نقطة jne label0;إن لم نصل نقفز عائدين إلى بداية العملية mov ah,1;خدمة أخذ حرف من المستخدم سنستخدمها للانتظار int 21h;تنفيذ مقاطعة أخذ الحرف من المستخدم mov ah,4ch;خدمة إنهاء البرنامج int 21h;تنفيذ خدمة الإنهاء end======================================================
10 - إجراء لطباعة القيمة العددية المحتواة في المسجل ah .. (وهو إجراء هام جدّاً لمن لا يعلم )
.model small .stack 100h .data .code mov al,0FFh;al;حفظ قيمة ما في call PrintAL;استدعاء دالة الطباعة mov ah,4ch;خدمة انهاء البرنامج int 21h;تنفيذ المقاطعة PrintAL proc mov ah,00h mov bl,0ah ;;;;;;;;;;;;;;; div bl push ax;ah;حفظ باقي القسمة وهو موجود داخل mov ah,00h div bl push ax mov ah,00h div bl push ax ;;;;;;;;;;;;;;;;;;; mov ax,0200h;خدمة طباعة حرف ;;;;;;;;;;;;;;;;;;; pop dx;نخرج الآحاد mov dl,dh;تذكر أنها محفوظة في الجزء العلوي ومقاطعة الطباعة تطبع الموجود في الجزء السفلي add dx,30h;تحويل الرقم إلى حرف int 21h;طباعة الآحاد pop dx;نخرج العشرات mov dl,dh add dx,30h int 21h;طباعة العشرات pop dx;نخرج المئات mov dl,dh add dx,30h int 21h;طباعة المئات mov dl,10;محرف نهاية السطر int 21h ;;;;;;;;;;;;;;; PrintAL endp end======================================================
الكود الحادي عشر .. فتح ملف باستخدام الخدمة 3D ثم قراءة عشر بايتات منه باستخدام الخدمة 3F من مقاطعة الدوز رقم 21
.model small .data filename db "test.txt",0;انتبه لاسم الملف ;ملاحظة : يجب أن يكون الملف موجوداً في نفس مكان وجود البرنامج .code mov dx,@data mov ds,dx mov ah,3dh;رقم خدمة فتح الملف mov al,00h;تحديد نوع فتح الملف للقراءة mov dx,offset filename;حفظ عنوان اسم الملف في مسجل البيانات int 21h ;ax;يتم حفظ المقبض في المسجل mov bx,ax;نقل المقبض إلى مسجل القاعدة mov ah,3fh;رقم خدمة القراءة من ملف mov cx,0ah;قراءة عشر بايتات int 21h;تنفيذ المقاطعة التي ستخزن عشر بايتات في العنوان الذي يشير له مسجل البيانات ;ملاحظة : عندما نستعمل مسجل البيانات فإنه يرتبط بمقطع البيانات mov ah,9;رقم خدمة طباعة سلسلة موجودة في مسجل البيانات int 21h;تنفيذ مقاطعة الدوس mov ah,4ch;رقم خدمة انهاء البرنامج int 21h;تنفيذ مقاطعة الدوس end======================================================
الكود الثاني عشر
النسخة المحسنة من الكود 10 (ليست محسنة كثيراً)
البرنامج التالي يحوي إجراء Procedure لطباعة القيمة العشرية للمسجل AX (هام جداً )
يمكن للكسابى نسخ الـprocedure وإضافته لكودهم مباشرة .. وهو يترك cx دون تأثير ويستعمل ax,bx,dx
الفكرة بسيطة جداً القسمة 5 مرات على 10 وحفظ الباقي في المكدس ثم إخراجه وطباعته
.model small .stack 100h .data .code mov ax,0FFFFh call PrintAX mov ah,4ch int 21h PrintAX proc mov dx,0000h mov bx,0Ah ;;;;;;;;;;;;;;; div bx push dx mov dx,0000h div bx push dx mov dx,0000h div bx push dx mov dx,0000h div bx push dx mov dx,0000h div bx push dx mov dx,0000h ;;;;;;;;;;;;;;;;;;; mov ax,0200h ;;;;;;;;;;;;;;;;;;; pop dx add dx,30h int 21h pop dx add dx,30h int 21h pop dx add dx,30h int 21h pop dx add dx,30h int 21h pop dx add dx,30h int 21h mov dl,10 int 21h ;;;;;;;;;;;;;;; ret PrintAX endp end======================================================
الكود الثالث عشر : طباعة القيمة العشرية لمحتوى ax (الكود المحسّن)
يمكنك أخذ الإجراء مباشرة مع العلم أنه لا يؤثر على أي مسجّل بداخله , استعمله وأنت مرتاح
.model small .stack 100h .data .code mov ax,0FFFFh call PrintAX mov ah,4ch int 21h PrintAX proc push ax;حفظ قيم المسجلات في المكدس push bx push cx push dx mov bx,0Ah;نقسم على 10 لذلك نحفظه في مسجل القاعدة ;;;;;;;;;;;;;;; mov cx,5;we will loop 5 times StartDiv: mov dx,0000h;dx should be zero when deviding div bx;devide on 10 push dx;حفظ باقي القسمة في المكدس loop StartDiv mov ax,0200h;print charachter function number mov cx,5;we will loop 5 times StartPop: pop dx add dx,30h int 21h loop StartPop mov dl,10 int 21h ;;;;;;;;;;;;;;; pop dx;استعادة جميع المسجلات المحفوظة بترتيب معاكس للحفظ pop cx pop bx pop ax ret PrintAX endp end======================================================
الكود الرابع عشر
يحتوي إجراء قراءة عدد (يجب أن يكون العدد أقل من 65536 )
الكود التالي يقرأ عدداً ثم يقوم بطباعته باستخدام الإجراء الذي كتبناه سابقاً
;get unsigned short integer .model small .stack 100h .data .code call readUSI;;get unsigned short integer ;the result stored in bx call printEndOfLINE; mov ax,bx call printAX; mov ax,4c00h;الخروج من البرنامج int 21h; printEndOfLINE proc mov ah,02h; mov dl,0Ah; int 21h;print end of line ret printEndOfLINE endp readUSI proc mov bx,0;we will save result in bx mov cx,0Ah;we will multiply by 10 in every loop cycle getChar: mov ah,01;read charachter function int 21h;now charachter stored in al cmp al,30h;compare with zero jl endRead;if we get less than zero xchg ax,bx;ax=result,bl=character mul cx;now ax=result*10 mov bh,0;bx=character sub bx,30h;turn from ascii value to integer value add ax,bx;ax=result mov bx,ax;bx=result jmp getChar endRead: ret readUSI endp PrintAX proc push ax;حفظ قيم المسجلات في المكدس push bx push cx push dx mov bx,0Ah;نقسم على 10 لذلك نحفظه في مسجل القاعدة ;;;;;;;;;;;;;;; mov cx,5;we will loop 5 times StartDiv: mov dx,0000h;dx should be zero when deviding div bx;devide on 10 push dx;حفظ باقي القسمة في المكدس loop StartDiv mov ax,0200h;print charachter function number mov cx,5;we will loop 5 times StartPop: pop dx add dx,30h int 21h loop StartPop call printEndOfLINE; ;;;;;;;;;;;;;;; pop dx;استعادة جميع المسجلات المحفوظة بترتيب معاكس للحفظ pop cx pop bx pop ax ret PrintAX endp end======================================================
الكود الخامس عشر
استخدمت الإجراءات الخاصة بالقراءة والطباعة لقراءة عددين من المستخدم وطباعة المجموع
;get unsigned short integer .model small .stack 100h .data getA_Message db "Please Enter The First Number $" getB_Message db "Please Enter The Second Number $" resultIs_Message db "The result is $" .code mov ax,@data mov ds,ax mov ah,09h;print string function mov dx,offset getA_Message int 21h call readUSI;;read unsigned short integer push bx;save a call printEndOfLINE; mov dx,offset getB_Message int 21h call readUSI;;read seconf number push bx;save b ;the result stored in bx call printEndOfLINE; mov dx,offset resultIs_Message int 21h pop ax pop bx add ax,bx call printAX; mov ax,4c00h;الخروج من البرنامج int 21h; printEndOfLINE proc push ax push dx mov ah,02h; mov dl,0Ah; int 21h;print end of line pop dx pop ax ret printEndOfLINE endp readUSI proc;save result in bx push ax push cx push dx mov bx,0;we will save result in bx mov cx,0Ah;we will multiply by 10 in every loop cycle getChar: mov ah,01;read charachter function int 21h;now charachter stored in al cmp al,30h;compare with zero jl endRead;if we get less than zero xchg ax,bx;ax=result,bl=character mul cx;now ax=result*10 mov bh,0;bx=character sub bx,30h;turn from ascii value to integer value add ax,bx;ax=result mov bx,ax;bx=result jmp getChar endRead: pop dx pop cx pop ax ret readUSI endp PrintAX proc push ax;حفظ قيم المسجلات في المكدس push bx push cx push dx mov bx,0Ah;نقسم على 10 لذلك نحفظه في مسجل القاعدة ;;;;;;;;;;;;;;; mov cx,5;we will loop 5 times StartDiv: mov dx,0000h;dx should be zero when deviding div bx;devide on 10 push dx;حفظ باقي القسمة في المكدس loop StartDiv mov ax,0200h;print charachter function number mov cx,5;we will loop 5 times StartPop: pop dx add dx,30h int 21h loop StartPop call printEndOfLINE; ;;;;;;;;;;;;;;; pop dx;استعادة جميع المسجلات المحفوظة بترتيب معاكس للحفظ pop cx pop bx pop ax ret PrintAX endp end======================================================
الرابط الأصلي
الكود السادس عشر في الرابط التالي
;get unsigned short integer .model small .stack 100h .data getA_Message db "Please Enter The First Number $" getB_Message db "Please Enter The Second Number $" getFunction_Message db "Please Enter The Operator (+,-,*,/) $" resultIs_Message db 10,13,"The result is $" UnknownOperator db "Unknown Operator !!",10,13,'$' ErrorDivideByZero db "Error , Divide by Zero !!",10,13,'$' .code mov ax,@data mov ds,ax mov ah,09h;print string function mov dx,offset getA_Message int 21h call readUSI;;read unsigned short integer push bx;save a call printEndOfLINE; mov dx,offset getB_Message int 21h call readUSI;;read second number push bx;save b call printEndOfLINE; mov dx,offset getFunction_Message int 21h call getOperator;return cl={'*','+','-','/'}={42,43,45,47} mov dx,offset resultIs_Message int 21h pop bx pop ax call doOperatorAXClBX; call printAX; mov ax,4c00h;الخروج من البرنامج int 21h; getOperator proc;return cl={*,+,-,/} push ax mov ah,1 int 21h mov cl,al pop ax ret getOperator endp doOperatorAXClBX proc;{*,+,-,/}={42,43,45,47} isSum: cmp cl,43 jne isMul add ax,bx ret isMul: cmp cl,42 jne isSub mul bx ret ;By Mostafa 0x36a2 isSub: cmp cl,45 jne isDiv sub ax,bx ret isDiv: cmp cl,47 jne unKnown mov dx,00h cmp bx,0 jne doDiv mov dx,offset ErrorDivideByZero mov ah,9 int 21h ret doDiv: div bx ret unKnown: mov dx,offset UnknownOperator mov ah,9 int 21h ret doOperatorAXClBX endp printEndOfLINE proc push ax push dx mov ah,02h; mov dl,0Ah; int 21h;print end of line pop dx ;arabteam2000 pop ax ret printEndOfLINE endp readUSI proc;save result in bx push ax push cx push dx mov bx,0;we will save result in bx mov cx,0Ah;we will multiply by 10 in every loop cycle getChar: mov ah,01;read charachter function int 21h;now charachter stored in al cmp al,30h;compare with zero jl endRead;if we get less than zero xchg ax,bx;ax=result,bl=character mul cx;now ax=result*10 mov bh,0;bx=character sub bx,30h;turn from ascii value to integer value add ax,bx;ax=result mov bx,ax;bx=result jmp getChar endRead: pop dx pop cx pop ax ret readUSI endp PrintAX proc push ax;حفظ قيم المسجلات في المكدس push bx push cx push dx mov bx,0Ah;نقسم على 10 لذلك نحفظه في مسجل القاعدة ;;;;;;;;;;;;;;; mov cx,5;we will loop 5 times StartDiv: mov dx,0000h;dx should be zero when deviding div bx;devide on 10 push dx;حفظ باقي القسمة في المكدس loop StartDiv mov ax,0200h;print charachter function number mov cx,5;we will loop 5 times StartPop: pop dx add dx,30h int 21h loop StartPop call printEndOfLINE; ;;;;;;;;;;;;;;; pop dx;استعادة جميع المسجلات المحفوظة بترتيب معاكس للحفظ pop cx pop bx pop ax ret PrintAX endp end==================================================
انتهى نقل الأكواد, الأكواد السابقة كتبتها أثناء تعلمي للغة وهي الآن مرجع مفيد لمن يريد البدء بها
ليست هناك تعليقات:
إرسال تعليق