السلام عليكم ورحمة الله وبركاته
اخواني انا مبتدئ بلغة الاسمبلي
اريد جمع عددين عن طريق ادخالهم من لوحة المفاتيح ثم عرض الناتج بعد ذلك
ارفقت الكود الذي كتبته و اتمنى ممن لديه الخبر توجيهي لمكان الخطأ
وشكرا جزيلا لكم
السلام عليكم
اخي الدالة int 21 ah = 01h تقوم بقراءة حرف من ملحق ادخال وتخرجه إلى ملحق إخراج، مثلا لوحة المفاتيح و الشاشة، ثم تضعه في المسجل al ، و بما أنك تريد إدخال سلسلة من الحروف و ليس حرفا واحدا يجب عليك أن تصنع حلقة.
لنفترض أنك تريد جمع عددين صحيحين موجبين و انك ستستخدم مفاتيح الأرقام و المفتاح VK_RETURN فقط.
اول شيء تقوم به هو قراءة سلسلة الحروف، ثم تحولها إلى عدد، ثم تقوم بعملية الجمع، ثم تحول العدد الناتج إلى سلسلة حرفية، ثم تخرجها إلى الشاشة.
لكي تقوم بقراءة سلسلة من الأرقام استعمل الحلقة التالية
next_degit: mov ah, 01h int 21h jmp next_degit
نظريا هذه الحلقة تقوم بالقرءة الى مالانهاية لذلك يجب ان تضع شرطا للخروج، أي انك تقول للبرنامج أنك انتهيت من ادخال العدد عند الضغط على المفتاح VK_RETURN .
VK_RETURN = 0Dh
next_degit: mov ah, 01h int 21h cmp al, 0Dh je eval jmp next_degit eval:
هذا الكود ليس كافيا لأن الرقم الذي تدخله يضيع في كل مرة تدخل رقما جديدا، لذلك يجب عليك حفظ الرقم في كل مرة تدخله. الناتج هو سلسلة من الأرقام في الذاكرة.
ملحوظة : يمكنك استخدام الدالة int 21h, ah = 0Ah dx = offset التي تغنيك عن العملية السابقة حيث تقوم بقراءة المفاتيح إلى أن تضغط على المفتاح VK_RETURN ثم تحفظها في الذاكرة المشار إليها في dx .
في الكود التالي لم أقم بتخصيص مساحة من الذاكرة لحفظ السلسلة وإنما استخدمت المكدس، يمكنك استخدام الطريقة الأولى، ولا تنسى إضافة القيمة 0 في آخر السلسلة.
يلزمنا معرفة عدد الارقام التي أضفناها للمكدس حتى نتمكن من استرجاعها لذلك سنستعمل المسجل cx كعداد.
لم اقم بتكديس قيمة الكود أسكي للأرقام وإنما القيمة الحقيقية لها وذلك باستعمال العلاقة التالية X = 'X' - 30h .
next_degit: mov ah, 01h int 21h cmp al, 0Dh je eval cbw sub ax, 30h push ax inc cx jmp next_degit eval:
الكود التالي يقوم بتحويل السلسلة إلى العدد الصحيح المكافئ وذلك باستعمال العلاقة التالية : مثلا لدينا رقم الآحاد يساوي 5 و رقم العشرات يساوي 2 و رقم المئات يساوي 7 ،إذن قيمة العدد تكون هي 7 * 100 + 2 * 10 + 5 * 1
النتيجة توضع في المسجل di .
eval: and cx, cx jz post pop ax mul bx add di, ax mov ax, 000Ah mul bx mov bx, ax dec cx jmp eval
بعد ذلك نحفظ العدد في الذاكرة
post: lea bx, A mov word ptr [bx], di
هذا الكود غير تام، يلزمه دالة إخراج print_value التي ستقوم ببرمجتها بنفسك .قم بالتفكير بخوارزمية تحويل عدد إلى سلسلة حرفية ثم استعمل الدالة int 21, ah = 09h dx = offset التي تقوم بإخراج سلسلة حرفية إلى الشاشة.
lea ax, A push ax call scan_value mov dl, 0Ah mov ah, 02h int 21h lea ax, B push ax call scan_value mov ax, A add ax, B mov R, ax jmp end scan_value proc xor cx, cx mov bx, 0001h xor di, di next_degit: mov ah, 01h int 21h cmp al, 0Dh je eval cbw sub ax, 30h push ax inc cx jmp next_degit eval: and cx, cx jz post pop ax mul bx add di, ax mov ax, 000Ah mul bx mov bx, ax dec cx jmp eval post: pop ax pop bx mov word ptr [bx], di push ax ret scan_value endp end: mov ah, 4ch int 21h
function Factorial(N: LongWord):LongWord; assembler; asm CMP EAX, 1 JLE @END MOV ECX, EAX DEC ECX @CONTINUE: MUL ECX LOOP @CONTINUE RET @END: XOR EAX, EAX INC EAX end;
الف شكر ع التوضيح
لكني مبتدأ جدا وكثير من الكود مافهمتوا
اذا اخي عليك بمراجعة عمل المقاطعات لا اكثر ولا اقل.
Do as I say, not as I do
We are Anonymous. We are Legion. We don't forgive. We don't forget
هذا الموضوع مغلق.