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

في حاجة إلى امثلة!

مغلقرائج
بدأه منسيه في 30 مايو 2004 · 51 رد · 5,045 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#26

السلام عليكم,

شكرا للأخ أحمد.

إلى اللقاء.

#27

السلام والرحمة

الظاهر اني فعلا تسرعت مثل ما قلت اخوي chik ،مثل ما تعرف الامتحانات على الابواب عندنا وكنت اريد المراجعة معكم عن طريق حل التمارين،اتمنى ان احد يشارك في عرض الاسألة!! شرايكم؟؟

#28

السلام عليكم

اليكم تمرين بسيط:

إكتب برنامج يحصل من المستخدم على كلمه , ثم يقم بعكس احرف الكلمه وكتابتها.

مثال

type a word please : Hello world

dlrow olleH

والسلام

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#29

السلام عليكم

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

include irvine32.inc

.data
aword	byte	50 dup(?),0
cont	dword	?
P1	byte	"Type a word please :",0

.code
main	proc	
	mov	edx,offset p1 
	call	writestring
	mov	edx,offset aword
	mov	ecx,50
	call	readstring
	mov	cont,eax

	call	crlf
	mov	esi,cont
	dec	esi
	mov	ecx,cont
	jecxz	skip
L1:	mov	al,aword[esi]
	call	writechar
	dec	esi
	loop	L1

skip:	exit
main	endp
end	main	
end

في انتظار البقية والتعليقات...تحياتي

#30

السلام عليكم,

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

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

اقتباس
mov esi,cont

فهذا ليس كافي حيث أن الرجستر سيكون فيه طول الجملة وهذه ستكون صحيحة طالما ابتدأت الجملة من الصفر وهذا لن يكون دائما صحيح .

الشيء الآخر الذي أريد أن أقوله وقد لا تكون له أهمية كبيرة في وقتنا هو أن الأمر jecxz قد ضهر للبروسسور 386 وما فوق وعلينا أن نعلم هذا إذا كانت لا زالت لدينا حواسيب في الكهف.

وكما أن هذا الأمر كان يجب أن يقدم شيئا ما فإذا كان cont=0 في الأول فلا داعي للقيام بالعمليات :

اقتباس
mov esi,cont

dec esi

ففي هذه الحالة فهذان السطران لا يهمان.

هذه بعض الآراء في انتضار المزيد من المناقشة.

إلى اللقاء.

#31

السلام عليكم

هذا هو الحل:

Title Reverse String
.486
.model Flat, stdcall
option casemap :none


include c:\masm32\include\kernel32.inc
include c:\masm32\include\masm32.inc

includelib c:\masm32\lib\kernel32.lib
includelib c:\masm32\lib\masm32.lib
.data 
Msg1 DB "Please Enter a String Value : ",0
Msg2 DB "The reversed value of your String is : ",0

.data?
myString DB 50 dup (?)
myReverse DB 50 dup (?)
.code

start:

invoke StdOut, addr Msg1

invoke StdIn, addr myString,sizeof myString


mov esi, OFFSET myString
mov edi, OFFSET myReverse

xor ecx,ecx
xor eax, eax
@@:
push eax
inc ecx
lodsb
test al, al
jnz @B

@@:
pop eax
stosb
loop @B


invoke StdOut, addr Msg2
invoke StdOut, addr myReverse
invoke ExitProcess,0
end start

لو فيه اشياء غير واضحه الرجاء طرح اسئله

والسلام

revers.zip

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#32

اهلا وسهلا اخوي chik

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

ما فهمت قصدك اخوي، يعني شلون (كيف) ما اشرنه إليه؟؟

اقتباس
الشيء الآخر الذي أريد أن أقوله وقد لا تكون له أهمية كبيرة في وقتنا هو أن الأمر jecxz قد ضهر للبروسسور 386 وما فوق وعلينا أن نعلم هذا إذا كانت لا زالت لدينا حواسيب في الكهف.

وكما أن هذا الأمر كان يجب أن يقدم شيئا ما فإذا كان cont=0 في الأول فلا داعي للقيام بالعمليات :

اهوه اعتقد ان في كل برنامج المفروض نحاسب للحالة العامة( اللي اهيه في مثالنه ادخال ولو حرف واحد) وفي نفس الوقت نحاسب اذا ما كان فيه اي معلومات ادخلت من اليوزر، في ذي الحالة jecxz ما راح ينفذ الخطوتين وبينتقل إلى skip على طول

#33

السلام عليكم,

الأخت منسيه : كان قصدي ما يلي :

خلال برنامجك الرجستر esi يدل على عنوان الجملة ولكن هذا غير موجود في البرنامج حيث في البرنامج نجد mov esi,cont وهذه سيضع طول الجملة في الرجستر عوض عنوان ذاكرتها. فلو نفترض أن الجملة تكون في العنوان 0 فهذا سيكوني صحيح وذلك بما أن esi سيكون فيه طول الجملة والجملة تبتدء في الصفر فكأن esi يدل على آخر حرف في الجملة . وهنا يجب أن نكون حذرين لأن هذا ليس دائما .

النقطة الثانية قلت أن الأمر jecxz ضهر مع 386 يعني أن هذا الأمر لا يشتغل في البروسسورات ما قبله.

وكذلك في الكود

اقتباس
mov esi,cont

dec esi

mov ecx,cont

jecxz skip

هو فعلا الأمر jecxz سيقوم بالتعرف إذا أعطى المستعمل كلمة ما أو لم يعطي شيئا وفي هذه الحالة سيكوني طول الجملة 0 وأيضا الرجستر cx .وكل ما قلته أن الأمر jecxz كان من الأحسن أن يسبق الأمر mov esi,cont لأن في حالة إذا كان ecx=0 فسوف لن نحتاج إلى الأمرين السابقين وسنربح بعض الوقت إذا لم نقم بإنجازهم.

أتمنى أن أكون واضحا وإلى اللقاء.

#34
اقتباس
الأخت منسيه : كان قصدي ما يلي :

خلال برنامجك الرجستر esi يدل على عنوان الجملة ولكن هذا غير موجود في البرنامج حيث في البرنامج نجد mov esi,cont وهذه سيضع طول الجملة في الرجستر عوض عنوان ذاكرتها.

انه ما قلت ان esi يدل على عنوان الجملة، لكن اهوه عبارة عن index ، لذلك وضعنا فيه طول الجملة علشان نمشي عليها حرف حرف

اقتباس
النقطة الثانية قلت أن الأمر jecxz ضهر مع 386 يعني أن هذا الأمر لا يشتغل في البروسسورات ما قبله.

وكذلك في الكود

QUOTE 

mov esi,cont

dec esi

mov ecx,cont

jecxz skip

هو فعلا الأمر jecxz سيقوم بالتعرف إذا أعطى المستعمل كلمة ما أو لم يعطي شيئا وفي هذه الحالة سيكوني طول الجملة 0 وأيضا الرجستر cx .وكل ما قلته أن الأمر jecxz كان من الأحسن أن يسبق الأمر mov esi,cont لأن في حالة إذا كان ecx=0 فسوف لن نحتاج إلى الأمرين السابقين وسنربح بعض الوقت إذا لم نقم بإنجازهم.

يا خوي اذا انه مو قاعدة احاسب لسرعة اشتغال البرنامج( مثل ما قلت في المثال السابق) كيف تبغيني احاسب حق الجهاز ومميزاته اذا كان قبل 386 او بعده؟؟؟

طبعا انت كلامك صح بس انه مبتدأة ومو حاطة في بالي الاساسيات الصحيحة للبرمجة

اما بالنسبة للكود ، حتى لو حاسبنه بعد بنحتاج إلى انستركشن علشان نتأكد اذا في انبوت او لا؟ عدل او لا؟؟

يا ريت تحط لنه طريقتك لحل البرنامج علشان افهم قصدك اكثر

اشكرك يا خوي على مناقشتك الجادة، ومثل ما قلت الظاهر ان البقية(باستثناء الاخ احمد غريب) كلهم هربوا ;)

تحياتي...منسيه

#35

السلام عليكم

اقتباس
اشكرك يا خوي على مناقشتك الجادة، ومثل ما قلت الظاهر ان البقية(باستثناء الاخ احمد غريب) كلهم هربوا

الاخت منسيه اعتقد ان ظروف الاختبارات هى سبب تغيب الاعضاء عن المشاركه, الحمد لله انا خلصت اخر إختبار من 10 سنوات مضت.

والسلام

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#36

السلام عليكم,

الأخت منسيه :

عندك حق في التدخل الأول فرغم أني قرات البرنامج عدة مرات فكل ما أقرأ :

mov al,aword[esi] أقرأها mov al,word ptr[esi] ففي هذه الحالة الرجستر esi يكون يدل على عنوان الجملة ورغم أن في هذا خطء أيضا لأن al ليس من صنف الوورد وربما الذي أعماني عن هذا هو تسمية aword .

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

إلى اللقاء.

#37

السلام عليكم

اقتباس
الأخت منسيه :

عندك حق في التدخل الأول فرغم أني قرات البرنامج عدة مرات فكل ما أقرأ :

mov al,aword[esi] أقرأها mov al,word ptr[esi] ففي هذه الحالة الرجستر esi يكون يدل على عنوان الجملة ورغم أن في هذا خطء أيضا لأن al ليس من صنف الوورد وربما الذي أعماني عن هذا هو تسمية aword .

عادي عادي، اكيد انت بعد الامتحانات مدوختك

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

إن شاء الله اوصل لهذا المستوى ، وما راح اوصل اذا ما في احد كرني وعلمني مثلك يا خوي( خذ راحتك)، بس لو مو الامتحانات على الابواب :')

وجايبت لكم اليوم سؤال شوي ازعجني، ياريت تساعدوني فيه:

Write a sequence of assembly instruction that test if the bit combination 100 is presented in ax or not. For example, 100 is present in 1001001101011010b, however, its not in 10010101101101110b.if the bit combination is present set the carry bit, otherwise clear the carry bit.

HINT: one possible solution to ese SHR or SHL and AND instruction in a loop.

في انتاظركم،

#38

السلام عليكم,

سأعطيك فكرة يمكن أن ننجز بها هذا :

نضع في قيمة رجستر ما مثل bx قيمة 0 في الأول وهذا سيحسب لنا عدد المرات الموفقة - وأعني بالتوفيق هنا العثور على 100 هكذا - ندور الرقم مرة إلى اليسار وإذا كان 1 نضع في bx قيمة 1 ثم نعاود الدوران فإذا كان مرة أخرى 1 سنعيد مرة أخرى 1 في الرجستر bx دائما وفي الحالة الأخرى نزيد 1 إلى bx وكل مرة نقارن هذا الرجستر فإذا وصلت قيمته 3 ننهي الدوران ونقول أن ما نريد البحث عنه موجود.

وبعجالة سيكون البرنامج على الشكل التالي وأنا أكتبه مباشرة هكذا دون تجربة ودون التأكد إذا ما كانت هناك أخطاء ونطلب من الله أن لا ينسينا ويسهينا:

mov cx,16   عدد البتات نفترضها 16 
mov bx,0   نضع في العداد 0
mov ax,TheWantedNumber  نضع في الرجستر الرقم الذي نريد البحث فيه

TheLoop:

shl ax,1   ندور الرجتر يسارا مرة واحدة
jnc  ZeroBit   إذا كان البت الأخير 0
mov bx,1   البت 1 نجعل bx يساوي 1 
loop  TheLoop   نعيد اللف والدوران ...

ZeroBit:  البت الأخير كان 0

cmp bx,0  يعني أن انتيجة السابقة لم تكن 1 فهذا لا يهمنا
loopz TheLoop  نعاود

inc bx  نضيف 1 إلى الرجستر
cmp bx,3     إذا وصلنا إلى 3 يعني التوفق
jz  Ok_Found 
loop TheLoop  الإعادة
;If we arrive here it means not found


Ok_Found:
;Here it means we have found the sequence

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

إلى اللقاء.

#39

امممم

ما ادري، بفكر في الموضوع وبحاول استفيد من الفكرة علشان احل السؤال، واذا انحل بجرب بطرق ثانية إن شاء الله، شكرا ياخوي

#40

السلام عليكم

mov ecx,16
state0:

shl ax,1
jc state1tmp

loop state1

jmp no100

state1tmp:
dec ecx

state1:
shl ax,1
jnc state2tmp
loop state1

jmp no100

state2tmp:
dec ecx

state2:
shl,1
jc state1tmp

stc
jmp done.

no100:
clc
done:

والسلام

تم تعديل هذه المشاركة بواسطة احمد غريب في 12 يونيو 2004 في 00:52

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#41

السلام عليكم

فكرة الحل السابق لإجاد العدد 100 بسيطه جداً, إقتبستها من finite-State Mashines, والفكره مشروحه فى كتب برمجه كثيره منها Irvine Kip, والذى شرحها صفحة 211.

ارفق ايضاً رسم بيانى للحل على طريقة finite-State Machines.

والسلام

post-79-1087051059_thumb.gif

لا إله إلا الله محمد رسول الله

busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.

#42

السلام عليكم...عدنا

شكرا اخي احمد غريب على المشاركة، انه ما كنت اعرف كيف ابدأ الحل لكن طريقتكم في الحل وصلت لي المطلوب الحمدلله، وقدرت احل السؤال اعتماداَ على طريقت حلكم اخواني، شوفوها وعطونه رايكم:

include irvine32.inc
.data 

.code
main	proc
	mov	ax,1001011101011110b
	mov	cx,16
  
B:	cmp	cx,0
	jcxz	no
	shl	ax,1
	jc	search
	dec	cx
	jmp	B

search:	push	cx
	mov	cx,2
	L:	shl	ax,1
  jc	outt
  loop	L
  pop	cx
  jmp	yes
  
outt:	pop	cx
	dec	cx
	jmp	B
	jmp	endSE

yes:	stc
	call	dumpregs
	jmp	endSE
  
no: clc
    call	dumpregs
  
endSE:  exit

main	endp
end	main
end

واذا عندكم اسألة بعد اتمنى تواصلون!!

تحياتي

#43

السلام عليكم,

وحتى هذا حل . ويمكن أن نزيد في البرنامج كمثل أن نخليه يعطينا عدد المرلت التي عثر فيها على ما نريد .

والملاحظة التي أريد أن أقولها هي نفترض أن العدد 100 غير موجود في العدد وأن العدد ينتهي ببت 1 كمثلا نقول نريد أن نبحث في العدد 1 . فطبعا :

اقتباس
B: cmp cx,0

jcxz no

shl ax,1

jc search

dec cx

jmp B

سيقوم بالبحث عن 1 في 15 بت يسارا ولن يعثر على شيء وحين يصل إلى البت الأخير طبعا سيحصل على 1 ومن تم ينتقل إلى :

اقتباس
search: push cx

mov cx,2

L: shl ax,1

jc outt

loop L

pop cx

jmp yes

وهنا سيقوم بالبحث مرتين رغم أننا انتهينا من البتات وهذا قد يعطينا جوابا خطءا.

فم هو نظرك.

إلى اللقاء.

تم تعديل هذه المشاركة بواسطة chik في 16 يونيو 2004 في 17:12

#44

فعلا كلامك صح مئة بالمئة، اممم

فكرت في حل بس مو مقتنعه فيه، شرايك لو نخليه يشيك cx قبل ليعمل له push واذا كان يساوي الواحد نخليه ينهي البرنامج jmp no؟؟

في الانتظار

#45

السلام عليكم,

هذا قد يحل هذه الإشكالية.

جاءتني فكرة الآن يمكن أن تصلح لهذا وهي على ما أضن فكرة سهلة وربما تكون فكرة جميلة وهي كالتالي.

ندور العدد يسارا وحين يكون 1 نسجل رقم مكانه في درجة البتات - نفترض مثلا أن البت في المكان 14 قيمته 1 نحتفض بالعدد 14 - ونستمر بالدوران وحين نلتقي المرة القادمة ب 1 نسجل أيضا قيمة مكانه ومن هنا يضهر الحل حيث يكفي أن ننقص الرتبة الأولى بالثانية فإذا كانت أكبر من 2 يعني أن بين هذين القيمتين توجد أكثر من 2 أصفار وهذا يدل على أننا عثرنا على النتيجة وفي الحالة الأخرى نستمر حتى النهاية.

نفترض أننا نحاول العثور على 100 في العدد 0011010001010101 البرنامج يعمل كالتالي سيعثر على العدد 1 في الرتبة 13 - نفترض أننا نبدأ بالرتبة 0 - نضع مثلا في BX قيمة 13 وسيعثر على 1 الموالي في 12 نضع مثلا 12 في dx ننقص dx من bx الحاصل يساوي 1 أقل من 2 لا يهمنا إذن نضع قيمة dx في bx ليصبح هذا الرتبة الأصلية الأولى ونعاود نفس الشيء. الضاهرة الثانية في المثال تكون بين 12 و 10 هذا أيضا لا يهمنا والضاهرة الموالية تكون بين 10 و 6 وبما أن الفرق 4 يعني بينهم 3 أصفار وهذا يدل على أن 100 موجودة هنا .

حاولت أن أعطي طريقة بسيطة تكون مفهومة ونعلم أنه إذا قمنا بهذا باستعمال اللوب كما ذكرت فإن رتبة الأعداد تكون عندنا مباشرة في CX .

أتمنى أن أكون مفهوما وإلى اللقاء.

#46

فكرة حلوة بعد، مشكور يا خوي والمسامحة على الازعاج

تحياتي... منسيه

#47

السلام عليكم,

لا إزعاج في النقاش وهذا قد يخلينا نرى الأشياء من عدة زوايا.

إلى اللقاء.

#48

السلام عليكم

عندي استفسار بالنسبة لل shl and shr، مثل ما تعرفون ان الshl is called fast multible ونقدر نضرب الاعداد باستخدامه في كود بسيط جدا، لكن السؤال... هل نقدر نستخدم الـ shr في كود ايضا للقسمه على اساس انه يعتبر fast division ؟؟ واذا نعم ياريت تساعدوني لو بالفكرة واكون شاكرة لكم

تحياتي..منسيه

#49

السلام عليكم,

هو بالفعل حين نكون في نضام عددي كيفما كان فإن هذا العدد يساوي 10 في نضامه في العشاري 10 تساوي 10 في الهكس 16 تكون هي 10 وفي الثنائي 2 هي 10 وإلى آخره. وفي أي نضام حين نريد الضرب في 10 نزيد 0 على اليمين وندفع الأرقام السابقة يسارا والعكس حين نريد القسمة على 10 نحذف الرقم الأول يمينا وهذا يعنى ندفع كل الأرقام يمينا. هذا عامة.

وفي النضام الثنائي بما أن 2 هي 10 فحين نريد ضرب عدد ما في 2 يكفي أن ندور العدد يسارا مرة واحدة والعكس حين نريد القسمة على 2 - وهنا نقول القسمة عددية يعني مثلا قسمة 4 أو 5 على 2 تعطينا نفس النتيجة.وكذلك بما أن 4 هي 100 فأيضا إذا أردنا الضرب في 4 ندور العدد مرتين يسارا وإلى غير ذلك.

ونعلم أن الضرب أو القسمة على 2 بهذه الطريقة هي أسرع من استعمال الضرب أو القسمة عن الطرق الأخى فهذه تستهلك أقل عدد من cycles للبروسسور.

إلى اللقاء.

#50

شكرا ياخوي

انه فاهمه الفكرة بس المشكلة في الكود، علشان اوضح اكثر بعرض مثال لضرب عددين word

mov  ecx,16
mov  bx,second;اقصد الرقم الثاني

L: shr  bx,1
jnc skip
push  ecx
mov  cl,count
movzx  eax,First
shl  eax,cl
add  answer,eax
pop  ecx
skip:  inc  count
loop  L

فهل بنفس الطريقة اقدر اقسم عددين؟؟ انه ما اعتقد انتوا شريكم؟؟

تم تعديل هذه المشاركة بواسطة منسيه في 18 يونيو 2004 في 18:22

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

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