السلام عليكم,
شكرا للأخ أحمد.
إلى اللقاء.
السلام عليكم,
شكرا للأخ أحمد.
إلى اللقاء.
السلام والرحمة
الظاهر اني فعلا تسرعت مثل ما قلت اخوي chik ،مثل ما تعرف الامتحانات على الابواب عندنا وكنت اريد المراجعة معكم عن طريق حل التمارين،اتمنى ان احد يشارك في عرض الاسألة!! شرايكم؟؟
السلام عليكم
اليكم تمرين بسيط:
إكتب برنامج يحصل من المستخدم على كلمه , ثم يقم بعكس احرف الكلمه وكتابتها.
مثال
type a word please : Hello world
dlrow olleH
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم
شكرا اخي على التجاوب، وهذا حل السؤال ، طبعا في كذا طريقة لحل التمرين بس انه استخدمت الاندكس :
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
في انتظار البقية والتعليقات...تحياتي
السلام عليكم,
فعلا البرنامج يقوم بالمقصود وهم يكتب مباشرة على الشاشة كل حرف يقرأه من الذاكرة . وربما نكتب الكلمة مقلوبة في الذاكرة حتى يمكن أن نستعملها أينما نشاء في البرنامج وقد يكون هذا مثال آخر. فنحن نعلم أننا لو أردنا أن نكتب الكلمة مقلوبة مرة أخرى فلا بد أن نعيد قلبها من جديد لأننا لا نتوفر عليها.
والملاحظة الأخرى هي أننا استعملنا الرجستر esi ليدل على الكتابة التي أدخلها المستعمل ولكن لم نشر إلى ذلك في البرنامج فقط على ما رأيت هناك :
اقتباسmov esi,cont
فهذا ليس كافي حيث أن الرجستر سيكون فيه طول الجملة وهذه ستكون صحيحة طالما ابتدأت الجملة من الصفر وهذا لن يكون دائما صحيح .
الشيء الآخر الذي أريد أن أقوله وقد لا تكون له أهمية كبيرة في وقتنا هو أن الأمر jecxz قد ضهر للبروسسور 386 وما فوق وعلينا أن نعلم هذا إذا كانت لا زالت لدينا حواسيب في الكهف.
وكما أن هذا الأمر كان يجب أن يقدم شيئا ما فإذا كان cont=0 في الأول فلا داعي للقيام بالعمليات :
اقتباسmov esi,contdec esi
ففي هذه الحالة فهذان السطران لا يهمان.
هذه بعض الآراء في انتضار المزيد من المناقشة.
إلى اللقاء.
السلام عليكم
هذا هو الحل:
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
لو فيه اشياء غير واضحه الرجاء طرح اسئله
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
اهلا وسهلا اخوي chik
اقتباسوالملاحظة الأخرى هي أننا استعملنا الرجستر esi ليدل على الكتابة التي أدخلها المستعمل ولكن لم نشر إلى ذلك في البرنامج فقط على ما رأيت هناك :
ما فهمت قصدك اخوي، يعني شلون (كيف) ما اشرنه إليه؟؟
اقتباسالشيء الآخر الذي أريد أن أقوله وقد لا تكون له أهمية كبيرة في وقتنا هو أن الأمر jecxz قد ضهر للبروسسور 386 وما فوق وعلينا أن نعلم هذا إذا كانت لا زالت لدينا حواسيب في الكهف.وكما أن هذا الأمر كان يجب أن يقدم شيئا ما فإذا كان cont=0 في الأول فلا داعي للقيام بالعمليات :
اهوه اعتقد ان في كل برنامج المفروض نحاسب للحالة العامة( اللي اهيه في مثالنه ادخال ولو حرف واحد) وفي نفس الوقت نحاسب اذا ما كان فيه اي معلومات ادخلت من اليوزر، في ذي الحالة jecxz ما راح ينفذ الخطوتين وبينتقل إلى skip على طول
السلام عليكم,
الأخت منسيه : كان قصدي ما يلي :
خلال برنامجك الرجستر esi يدل على عنوان الجملة ولكن هذا غير موجود في البرنامج حيث في البرنامج نجد mov esi,cont وهذه سيضع طول الجملة في الرجستر عوض عنوان ذاكرتها. فلو نفترض أن الجملة تكون في العنوان 0 فهذا سيكوني صحيح وذلك بما أن esi سيكون فيه طول الجملة والجملة تبتدء في الصفر فكأن esi يدل على آخر حرف في الجملة . وهنا يجب أن نكون حذرين لأن هذا ليس دائما .
النقطة الثانية قلت أن الأمر jecxz ضهر مع 386 يعني أن هذا الأمر لا يشتغل في البروسسورات ما قبله.
وكذلك في الكود
اقتباسmov esi,contdec esi
mov ecx,cont
jecxz skip
هو فعلا الأمر jecxz سيقوم بالتعرف إذا أعطى المستعمل كلمة ما أو لم يعطي شيئا وفي هذه الحالة سيكوني طول الجملة 0 وأيضا الرجستر cx .وكل ما قلته أن الأمر jecxz كان من الأحسن أن يسبق الأمر mov esi,cont لأن في حالة إذا كان ecx=0 فسوف لن نحتاج إلى الأمرين السابقين وسنربح بعض الوقت إذا لم نقم بإنجازهم.
أتمنى أن أكون واضحا وإلى اللقاء.
اقتباسالأخت منسيه : كان قصدي ما يلي :خلال برنامجك الرجستر 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 او بعده؟؟؟
طبعا انت كلامك صح بس انه مبتدأة ومو حاطة في بالي الاساسيات الصحيحة للبرمجة
اما بالنسبة للكود ، حتى لو حاسبنه بعد بنحتاج إلى انستركشن علشان نتأكد اذا في انبوت او لا؟ عدل او لا؟؟
يا ريت تحط لنه طريقتك لحل البرنامج علشان افهم قصدك اكثر
اشكرك يا خوي على مناقشتك الجادة، ومثل ما قلت الظاهر ان البقية(باستثناء الاخ احمد غريب) كلهم هربوا ;)
تحياتي...منسيه
السلام عليكم
اقتباساشكرك يا خوي على مناقشتك الجادة، ومثل ما قلت الظاهر ان البقية(باستثناء الاخ احمد غريب) كلهم هربوا
الاخت منسيه اعتقد ان ظروف الاختبارات هى سبب تغيب الاعضاء عن المشاركه, الحمد لله انا خلصت اخر إختبار من 10 سنوات مضت.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم,
الأخت منسيه :
عندك حق في التدخل الأول فرغم أني قرات البرنامج عدة مرات فكل ما أقرأ :
mov al,aword[esi] أقرأها mov al,word ptr[esi] ففي هذه الحالة الرجستر esi يكون يدل على عنوان الجملة ورغم أن في هذا خطء أيضا لأن al ليس من صنف الوورد وربما الذي أعماني عن هذا هو تسمية aword .
فيما يخص التدخل الثاني أنا ذكرته لنعلم هذه الأشياء فقط . فربما عند البداية لا تهمنا بعض الأمور ولكن أقول أنه من الأحسن التعود على Optimization حتى تتمكن برامجنا بشيء من الإحترافية في المستقبل. وكان غرضي في هذا ليس هذا الموضوع بالذات بل محاولة فتح النقاش لأبواب أخرى.
إلى اللقاء.
السلام عليكم
اقتباسالأخت منسيه :عندك حق في التدخل الأول فرغم أني قرات البرنامج عدة مرات فكل ما أقرأ :
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.
في انتاظركم،
السلام عليكم,
سأعطيك فكرة يمكن أن ننجز بها هذا :
نضع في قيمة رجستر ما مثل 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
هذه محاولة أولية وإذا فكرنا أكثر يمكن معالجتها بطريقة ربما تكون أفضل.
إلى اللقاء.
امممم
ما ادري، بفكر في الموضوع وبحاول استفيد من الفكرة علشان احل السؤال، واذا انحل بجرب بطرق ثانية إن شاء الله، شكرا ياخوي
السلام عليكم
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 : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم
فكرة الحل السابق لإجاد العدد 100 بسيطه جداً, إقتبستها من finite-State Mashines, والفكره مشروحه فى كتب برمجه كثيره منها Irvine Kip, والذى شرحها صفحة 211.
ارفق ايضاً رسم بيانى للحل على طريقة finite-State Machines.
والسلام
لا إله إلا الله محمد رسول الله
busbar : يجب ان تدرك انه هناك حد ادنى للمعرفة المطلوبة قبل البدء في عمل أي شئ.
السلام عليكم...عدنا
شكرا اخي احمد غريب على المشاركة، انه ما كنت اعرف كيف ابدأ الحل لكن طريقتكم في الحل وصلت لي المطلوب الحمدلله، وقدرت احل السؤال اعتماداَ على طريقت حلكم اخواني، شوفوها وعطونه رايكم:
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
واذا عندكم اسألة بعد اتمنى تواصلون!!
تحياتي
السلام عليكم,
وحتى هذا حل . ويمكن أن نزيد في البرنامج كمثل أن نخليه يعطينا عدد المرلت التي عثر فيها على ما نريد .
والملاحظة التي أريد أن أقولها هي نفترض أن العدد 100 غير موجود في العدد وأن العدد ينتهي ببت 1 كمثلا نقول نريد أن نبحث في العدد 1 . فطبعا :
اقتباسB: cmp cx,0jcxz no
shl ax,1
jc search
dec cx
jmp B
سيقوم بالبحث عن 1 في 15 بت يسارا ولن يعثر على شيء وحين يصل إلى البت الأخير طبعا سيحصل على 1 ومن تم ينتقل إلى :
اقتباسsearch: push cxmov cx,2
L: shl ax,1
jc outt
loop L
pop cx
jmp yes
وهنا سيقوم بالبحث مرتين رغم أننا انتهينا من البتات وهذا قد يعطينا جوابا خطءا.
فم هو نظرك.
إلى اللقاء.
تم تعديل هذه المشاركة بواسطة chik في 16 يونيو 2004 في 17:12
فعلا كلامك صح مئة بالمئة، اممم
فكرت في حل بس مو مقتنعه فيه، شرايك لو نخليه يشيك cx قبل ليعمل له push واذا كان يساوي الواحد نخليه ينهي البرنامج jmp no؟؟
في الانتظار
السلام عليكم,
هذا قد يحل هذه الإشكالية.
جاءتني فكرة الآن يمكن أن تصلح لهذا وهي على ما أضن فكرة سهلة وربما تكون فكرة جميلة وهي كالتالي.
ندور العدد يسارا وحين يكون 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 .
أتمنى أن أكون مفهوما وإلى اللقاء.
فكرة حلوة بعد، مشكور يا خوي والمسامحة على الازعاج
تحياتي... منسيه
السلام عليكم,
لا إزعاج في النقاش وهذا قد يخلينا نرى الأشياء من عدة زوايا.
إلى اللقاء.
السلام عليكم
عندي استفسار بالنسبة لل shl and shr، مثل ما تعرفون ان الshl is called fast multible ونقدر نضرب الاعداد باستخدامه في كود بسيط جدا، لكن السؤال... هل نقدر نستخدم الـ shr في كود ايضا للقسمه على اساس انه يعتبر fast division ؟؟ واذا نعم ياريت تساعدوني لو بالفكرة واكون شاكرة لكم
تحياتي..منسيه
السلام عليكم,
هو بالفعل حين نكون في نضام عددي كيفما كان فإن هذا العدد يساوي 10 في نضامه في العشاري 10 تساوي 10 في الهكس 16 تكون هي 10 وفي الثنائي 2 هي 10 وإلى آخره. وفي أي نضام حين نريد الضرب في 10 نزيد 0 على اليمين وندفع الأرقام السابقة يسارا والعكس حين نريد القسمة على 10 نحذف الرقم الأول يمينا وهذا يعنى ندفع كل الأرقام يمينا. هذا عامة.
وفي النضام الثنائي بما أن 2 هي 10 فحين نريد ضرب عدد ما في 2 يكفي أن ندور العدد يسارا مرة واحدة والعكس حين نريد القسمة على 2 - وهنا نقول القسمة عددية يعني مثلا قسمة 4 أو 5 على 2 تعطينا نفس النتيجة.وكذلك بما أن 4 هي 100 فأيضا إذا أردنا الضرب في 4 ندور العدد مرتين يسارا وإلى غير ذلك.
ونعلم أن الضرب أو القسمة على 2 بهذه الطريقة هي أسرع من استعمال الضرب أو القسمة عن الطرق الأخى فهذه تستهلك أقل عدد من cycles للبروسسور.
إلى اللقاء.
شكرا ياخوي
انه فاهمه الفكرة بس المشكلة في الكود، علشان اوضح اكثر بعرض مثال لضرب عددين 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
هذا الموضوع مغلق.