الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

جمع عددين عن طريق قرائتهم من لوحة المفاتيح

مغلق
بدأه MesoOo في 10 مارس 2006 · 3 رد · 8,490 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته

اخواني انا مبتدئ بلغة الاسمبلي

اريد جمع عددين عن طريق ادخالهم من لوحة المفاتيح ثم عرض الناتج بعد ذلك

ارفقت الكود الذي كتبته و اتمنى ممن لديه الخبر توجيهي لمكان الخطأ

وشكرا جزيلا لكم

test.zip

#2

السلام عليكم

اخي الدالة 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;
#3

الف شكر ع التوضيح

لكني مبتدأ جدا وكثير من الكود مافهمتوا

#4

اذا اخي عليك بمراجعة عمل المقاطعات لا اكثر ولا اقل.

Do as I say, not as I do

We are Anonymous. We are Legion. We don't forgive. We don't forget

هذا الموضوع مغلق.

مواضيع مشابهة