2015/08/01

كود أسمبلي تحويل العدد من الترميز العشري إلى الترميز الثنائي

السلام عليكم ورحمة الله وبركاته
تتمّة لبرنامج الأخ Z3r0n3 في هذه المشاركة ..
البرنامج التالي يقوم بأخذ عدد بالترميز العشري وتحويله إلى الترميز الثنائي ولكن بشكل معكوس
وفق الخوارزمية التالية :
1- نقرأ رقماً من العدد (القراءة من اليسار إلى اليمين )
2- إذا كانت القيمة المقروءة هي نهاية السطر ننتقل للخطوة 4
3- نضرب العدد المحفوظ حتى الآن بـعشرة ونضيف له العدد المقروء وننتقل للخطوة 1
4- نقسم العدد على 2 ونطبع باقي القسمة ونكرر الخطوة حتى يصبح العدد صفراً .

وهذا هو الكود :
.model small
.stack 10h
.data
.code
;bx;هو الذي سيحتفظ بالرقم المدخل
GetTheNumber:
    mov ah,01h;تخزين رقم مقاطعة ادخال الحرف من المستخدم
    int 21h;
    cmp al,2Fh;مقارنة الدخل مع القيمة التي تأتي تحت الصفر مباشرة في جدول الآسكي
        jle end_;القفز إذا كانت القيمة أصغر أو تساوي .. أي أنها ليست رقما
    
    mov ch,al; نخزّن الدخل في مسجل آخر
    
    ;ضرب مسجل القاعدة بعشرة
    mov ax,bx;
    mov cl,0Ah;
    mul cl;
    mov bx,ax;
    
    ;نطرح قيمة الآسكي للرقم صفر .. فتصبح القيمة هي قيمة العدد تماما وليس قيمته في الآسكي
    sub ch,30h
    mov cl,ch
    mov ch,00h
    add bx,cx;نضيف المنزلة الجديدة إلى مسجل القاعدة الذي يخزّن القيمة الكلّية

jmp GetTheNumber
        
        end_:
printNewLine:
        mov ah,02h;قيمة المقاطعة الخاصة بطباعة حرف
        mov dl,0Dh;نضع الحرف المراد طباعته في مسجل البيانات
        int 21h;ننفذ المقاطعة ونطبع القيمة
        mov dl,0Ah
        int 21h
end printNewLine
            print:
                mov dx,bx;نضع قيمة العدد في مسجل البيانات
                and dx,1;نختبر إذا كان يقبل القسمة على اثنين
                add dx,30h;ونضيف له رقم الآسكي الخاص بالصفر فيصبح الآن يحتفظ بقيمة الآسكي للواحد أو الصفر
                int 21h;ننفذ مقاطعة طباعة الحرف الموجود في مسجل البيانات
                shr bx,1;نقسم القيمة المحفوظة على اثنين عن طريق الإزاحة
                cmp bx,0;نقارن هل صار الرقم صفرا
                    je kill;ننهي البرنامج في حال انتهاء الرقم
            jmp print;أو نكرر العملية حتى ينتهي الرقم
                    kill:
                        mov ah,4Ch;تخزين قيمة المقاطعة الخاصة بالخروج من البرنامج
                        int 21h;تنفيذ المقاطعة السابقة
end
 والكود التالي يقوم بطباعة العدد بالشكل الصحيح (وليس معكوس ) باستخدام push و pop  في المكدّس .
.model small
.stack 10h
.data
.code
;bx;هو الذي سيحتفظ بالرقم المدخل
GetTheNumber:
    mov ah,01h;تخزين رقم مقاطعة ادخال الحرف من المستخدم
    int 21h;
    cmp al,2Fh;مقارنة الدخل مع القيمة التي تأتي تحت الصفر مباشرة في جدول الآسكي
        jle end_;القفز إذا كانت القيمة أصغر أو تساوي .. أي أنها ليست رقما
    
    mov ch,al; نخزّن الدخل في مسجل آخر
    
    ;ضرب مسجل القاعدة بعشرة
    mov ax,bx;
    mov cl,0Ah;
    mul cl;
    mov bx,ax;
    
    ;نطرح قيمة الآسكي للرقم صفر .. فتصبح القيمة هي قيمة العدد تماما وليس قيمته في الآسكي
    sub ch,30h
    mov cl,ch
    mov ch,00h
    add bx,cx;نضيف المنزلة الجديدة إلى مسجل القاعدة الذي يخزّن القيمة الكلّية

jmp GetTheNumber
        
        end_:
printNewLine:
        mov ah,02h;قيمة المقاطعة الخاصة بطباعة حرف
        mov dl,0Dh;نضع الحرف المراد طباعته في مسجل البيانات
        int 21h;ننفذ المقاطعة ونطبع القيمة
        mov dl,0Ah
        int 21h
end printNewLine
                mov cl,0;نصفّر المسجل الذي سنستعمله كعدّاد
            reverse:;والآن سنقوم بعكس العدد الثنائي
                    mov dl,bl;\;
                    and dl,1 ;| نضع في المكدّس البت الأقل وزنا من العدد المحفوظ
                    push dx  ;/
                    inc cl;نزيد العداد
                    shr bx,1;نقسم العدد على اثنين
                    cmp bx,0;اذا وصلنا للصفر نذهب للطباعة
                    je print
                    jmp reverse;أو نكرر العملية
                print:
                cmp cl,0;اذا صار العداد صفر اخرج
                je kill
                mov ah,02;تخزين قيمة مقاطعة طباعة الرقم
                pop dx;نخرج من المكدّس البتّات بترتيب معاكس للإدخال
                add dx,30h ;نضيف قيمة الآسكي للصفر لنحصل على قيمة الآسكي للرقم المخزّن
                int 21h ;ننفذ مقاطعة طباعة الرقم وستطبع واحد أو صفر
                dec cl ;ننقص العداد
                jmp print
                    kill:
                        mov ah,4Ch ;مقاطعة انهاء البرنامج
                        int 21h
end
 والله وليّ التوفيق

ليست هناك تعليقات:

إرسال تعليق