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

سوال بسيط

مغلق
بدأه نورالدين في 27 مايو 2004 · 7 رد · 613 مشاهدة · في لغة Assembly لأنظمة 16, 32, 64 بت
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

البرنامج بسيط لكن في شغله تسببت في عدم الاجابه

السوال :اريد ان اعرف كم عدد تكرار كلمه ما في الجمله string

مثلا :

string: this is astudent

اريد ان ابحث عن كلمه is في حال وجودها في الجمله اريد ان اعرف كم مره تكررت

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

منتظر الاجابه

#2

هاه الاخ المشرف ايش قلت !

#3

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

في الحالات التي نتعامل مع مثل هذه الحالات غالبا ما نستعمل الأوامر scas أو loads وأضن هي المؤهلة في مثل هذه الحالات. وقد قمت بعدة أمثلة مثل هذا النوع وسأحول إحداها لمثل هذه الحالة وسيكون البرنامج كالتالي :

        .MODEL  SMALL, os_dos
        .code
        TheString:
	db  "this is a student is in missing",'$'; The string where to search
	Displ:
	db "The Number Of Times is :  " ; a message to display
Result:
	db 0,13,10,'$' ; in place of zero will be the result
start:
	push cs   ;push cs
	pop ds    ; mke all the segments the same value
	push ds
	pop es

	xor bl,bl ;Set the result=0
	lea di,TheString  ;put in di the offset of the string where to search
	mov dx,di;put in dx the same value
	add dx,40h    ;set dx over the end of string must be at least lenth + 2

_Repeat:	
	mov ax,'si'   ; put in ax the value to search for it is inverted is -> si
	repnz scasw   ;this will compare ax with the value in di
	cmp di,dx     ;have we finished the string
	ja Terminate  ;if yes
	inc bl        ;we have found one add 1 to bl
	jmp _Repeat   ;search for some other
    
Terminate:
	add bl,30h;add to bl 30h so it is ascii - we suppose the number of occurence is <10
    lea si,Result  ;put the result in its place
	mov [si],bl
	lea dx,Displ;display the result
mov ah,9
int 21h
        mov ah,4ch ;Terminate
        mov al,0
        int 21h
       

  


end start

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

إلى اللقاء.

#4
الاخ المشرف  شكرا علي الرد السريع

لدي بعض الملاحظات:

-عرفت result واعطيتها مقادير ؟ ارجو التوضيح

-ماهي الحاجه في push (seg) والي اعرفه نعمل درج وحذف لREGISTER ثم اليس الاولي ان نعمل درج وبعدين حذف

اقصد ل ds ؟

-mov dx,di كيف يتم النقل من byte -to-worde؟

-add dx,40h مالداعي لهدا الدستور؟

-repnz scaswلم يسبق لي ان عرفت بهدا الامر افضل استخدام البديل له

-cmp di,dx مقايسه بين 1 بايت و2 بايت؟

-ja معناهjump above or jumb not below\equal؟

علي العموم لا اعتقد ان البرنامج صحيح الا ؟ الله اعلم

افيدوني جزاكم الله خير وافضل ان تجريه فبل ان تجيب عليه وارجوا الرد السريع

شاكرا تعاونك سلفا

انت تعلم بان المقايسه بايت به بايت يشبه هذا السوال فی السی تابعstrstr

#5

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

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

وكما قلت مسبقا حين نتعامل مع strings فهنا يجب علينا أن نتعلم الأوامر scas و loads وإذا أضفنا لهم الأمر rep تصبح لنا قدرة قوية للتعامل مع مثل هذه الأشياء.

- فيما يخص سؤالك الأول push segment ففي البرنامج أريد أن أعطي لكل السكمنت نفس القيمة لأنني أفترض أن البرنامج ليس كبير والكل سيكون في سكمنت واحد. وهناك عدة لعمل ذلك وأنا أفضل طريقة push وإذا أردت أن تعملها بطريقة أخرى فكل حسب ميولاته.فمثلا حين نكتب :

push cs

pop ds

فإن البرنامج سيضع قيمة cs على الستاك وبعد pop سيضع هذه القيمة في ds وبعد هذا طبعا سيكون عندنا ds=cs .

اقتباس
mov dx,di كيف يتم النقل من byte -to-worde؟

أين ترى هنا نوع البايت فكلتا dx و di من نوع واحد.

اقتباس
add dx,40h مالداعي لهدا الدستور؟

هنا لا دستور ولا مشروع قانون كل ما في الأمر بما أن dx في الأول يشير إلى بداية الجملة حين زدت له أربعين سيشير إلى آخرها وربما شيئا ما أكثر لنحدد المجال الذي سوف نبحث فيه حتى لا نبحث في الذاكرة كلها . وبما أن الجملة طولها حوالي 30 وما فوق أعطيت 40 هكذا بدون حساب دقيق وإذا أردت يمكن أن تستبدلها بطول الجملة وأضف إليها 2 حتى لا تخلي شيئا.

اقتباس
repnz scaswلم يسبق لي ان عرفت بهدا الامر افضل استخدام البديل له

الأمر scasw يقارن محتوى ax مع محتوى الذاكرة المشار إليها ب ES:DI وبعد كل محاولة سيكبر di ب 2 في هخذه الحالة - وقد يصغر إذا أردنا أن نبحث مثلا عكسيا - وهذه نزيد لها الأمر repnz يعني Repeat if no equal سيقوم بالبحث طالما لا يعثر على ما في داخل ax

وهذا هو هدفنا.

اقتباس
انت تعلم بان المقايسه بايت به بايت يشبه هذا السوال فی السی تابعstrstr

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

أتمنى أني قد أعطيت بعض التوضيحات وإلى اللقاء.

وفي الملف المرفق إليك البرنامج مبني :

FindIs.exe

#6

اتمنی لو رسلت الملف بصورت .asm اوغيره تعرفexe.مابيفتح فايل اجرايي

شكرا علي جوابك

#7

عفوا یااخی لا تزعل منی البرنامج اشتغل صحیح مشکور ماقصرت والله یزیدک علما الی علمک

کانت المشکله فی :

- .MODEL SMALL, os_dos

حیث .s_dos, حذفتها

- : بعد the string & Displ خطا بمجرد حدفها حلت المشكله

لكن ليش بتتم المقايسه بصورت معكوس ؟

يعني si بدلا من is

ايضا لو تلاحظ بان is تكررت اربع مرات وليس مرتين كما هو الجواب في البرنامج

شكرا علي تعاونك

#8

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

اقتباس
لكن ليش بتتم المقايسه بصورت معكوس ؟

يعني si بدلا من is

الأمور تنقلب في الذاكرة وهذا من شغل البروسسور . وقد تبدو لنا غير طبيعية ولكنها في فائق الأهمية حين نعمل ما يسمى ب CAST أي تحويل المتغيرات مثلا من نوع إلى نوع آخر. فمثلا نفترض أن ax=1234h فهنا نعرف أن al=34h بينما ah=12h أما في الذاكرة فلو افترضنا أن ax سيكون في الذاكرة 1000 مثلا فستكون حالتها كما يلي :

1000 -> 34 al

1001 -> 12 ah

وهنا نلاحض أن الأمور قد انقلبت وهذا ما جعلنا نقلب is إلى si لأننا وضعناها في وورد.

اقتباس
ايضا لو تلاحظ بان is تكررت اربع مرات وليس مرتين كما هو الجواب في البرنامج

شكرا علي تعاونك

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

إلى اللقاء.

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

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