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

سؤال بسيط آخر في إسناد القيم للمتغيرات

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

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

حيا الله الإخوة جميعاً

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

السؤال هو : إذا قمت بتعريف متغير في قسم ال .data مثلاً

strA        db "A",0

الآن في القسم .code أريد أن أسند قيمة أخرى لهذا المتغير ، ماذا أفعل ؟

إن شاء الله اتوقع المرة هذه يسلم عليا أخي الحبيب أحمد غريب - خاصة وأنا عنده في القسم - حتى عشان يشعرني أنه (مش زعلان) مني :)

بارك الله فيكم

#2

بالمناسبة إن كان هناك كتاب مناسب فيه مثل هذه الفوائد مثل المتغيرات والثوابت ، فأرجو أن تدلوني عليه

بارك الله فيكم

#3

وعليكم السلام

حياك الله اخى محمد وانا مش ممكن ازعل منك بالعكس إنتا زي اخويا, انا بالفعل كنت عايز ارحب بيك فى المداخله الاوله وارد على سؤالك ولكن الاخ هاكرمان بارك الله فيه دائماً يسبقنا إلى الخير..

انا سعيد انك قررت تتعلم لغة الاسمبلى وإن شاء الله حساعدك بكل ما اعرف..

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

مثال

.data
strA        db "A",0
data.
mov esi,offset strA;هنا نضع عنوان المتغير فى esi افترض الان انك تريد تغير قيمته إلى B

mov al,'B';نضع القيمه B فى مسجل مثل al  او bl  او اى مسجل يحتمل قيمة بايت

mov byte ptr[esi],al;واخيراً نضع القيمه التى فى المسجل فى موقع الذاكره التى نريد تغيرها

مثال اخر

افترض ان لدينا النص text ونريد تغيرها إلى النص test مثلاُ

.data
strA        db "text",0

.code

mov esi,offset strA;هنا نضع عنوان المتغير فى esi افترض الان انك تريد تغير قيمة x إلى s

mov al,'s';نضع القيمه B فى مسجل مثل al  او bl  او اى مسجل يحتمل قيمة بايت
mov byte ptr[esi+2],al;واخيراً نضع القيمه التى فى المسجل فى موقع الذاكره التى نريد تغيرها

نضع الداله byte ptr حتى يعرف المترجم اننا نريد تغير قيمه من نوع بايت فقط, إذا اردت تغير قيمه من نوع word فإنك تضع word ptr وهكذا..

إن شاء الله اضع امثله اخرى لاحقاً ولكن الان لا اريد ان اضع امثله اكثر حتى لا تتعقد الامور..

بالتوفيق

والسلام عليكم

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

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

#4

بالنسبه للكتب هناك العديد إذا اردت كتاب ورقى فهناك كتاب إسمه assembly language for intel - based computers للكاتب Kip R. Irvine .

اما بالنسبه للمواقع فافضل موقع هو موقع izilione هناك ثلاث دروس للمتبدئين و اكثر من 30 درس للوندوز وتجدها على هذا الموقع

http://win32assembly.online.fr/tutorials.html

كذلك هناك ملفات الـHelp والتى تجدها فى المسار c:\masm32\help واهمها بالنسبه لك هو الملف ASMINTRO.HLP

كما انه يوجد العديد من الامثله فى ملف masm32

والسلام عليكم

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

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

#5

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

أولا الحمد لله تعالى انك مش زعلان :)

ثانياً جزاكم الله خيراً على الأسلوب الجميل والبسيط هذا

فعلا فهمت الآن إن شاء الله سأطبق ثم أخبرك بالناتج إن شاء الله

#6

طيب رائع

لكن سؤال كيف أسند قيمة أطول من حرف

بمعنى آخر ليست BYTE

لأني جربت DWORD فأظهر لي خطأ

فما الاختلاف هنا ؟ ما الذي يجب تغييره في الكود ؟

#7

السلام عليكم

شوف يا سى دى إحنا كتبنا byte ptr لما تعوز تغير word يبقى نستعمل word ptr وطبعاُ الword تتكون من 2 بايت .

مثال

.data
arrayWord word 1000h,2000,3000
.code
mov esi,offset arrayWord
mov ax,word ptr[esi];هنا نحصل على اول ورد 
...

mov bx,word ptr[esi+2];هنا نحصل على ثانى ورد لاحظ إننا نضيف 2 للوصول إلى الورد الثانى وذلك لان ورد واحد يساوى 2 بايت
...

mov cx,word ptr[esi+4];هنا نحصل على ثالث ورد هنا ايضاً نضيف 2*2 =4 بايت

لاحظ الان هذا المثال وقل لى ماذا تتوقع ان يكون محتوى ِْax بعد تشغيل هذا الكود

.data
myStr db 'ABCD',0
.code
mov esi,offset myStr
mov ax,word ptr[esi]

والسلام عليكم

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

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

#8

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

100%

حسب ما فهمت المفروض يكون محتوى ax هو ABCD

إذاً الآن إذا أردنا إشناد قيمة أخرى للمتغير myStr يكون الكود كالآتي :

          mov esi,offset myStr
          mov ax,"zzzz"
          mov word ptr[esi] ,ax

طبعاً خطأ :)

لكن تهت :(

مش عارف ليه كل ما أفكر في الأسيمبلي ألاقيها سهلة - لمدة خمس دقائق - بعد ذلك أتعمق في التفكير ... أتوه

#9

تقريباً صح بس فى خلل بسيط

الword تتكون من 2 بايت فقط لذلك إجابة السؤال هى ان ax تحتوى فقط على AB , إذا اردت ان تغير myStr اربع حروف فى خطوه واحده يجب ان تستخدم eax وهى 4 بايت على النحو التالى

mov esi,offset myStr
         mov eax,"zzzz"
         mov dword ptr[esi] ,eax

لاحظ انى استخدمن dword عشان اعرف انقل 4 بايت.

الاسمبلى سهله جداً خصوصاً 32 بت ولكن تحتاج إلى تعود لانها تختلف, المشكله هى إن المتعود يبرمج فى لغات اخرى بيكون غير متعود على إن كل شيئ مكشوف كما هو الحال فى لغه الاسمبلى...

افضل طريقه للتعلم هى ان تسئل عن كل شيئ لا تفهمه, لانه ضرورى تفهم كل شيئ, يعنى ما فيش نص ونص, لو فى جزئيه معينه إنتا مش فاهمها ربما تكون السبب فى عدم قدرتك على كتابة برنامج..

والسلام عليكم

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

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

#10

السلام عليكم

جزاك الله خيراً أخي الحبيب

طيب سؤال أخير - وأعتذر إن كنت قد أطلت عليك

ماذا لو أردت إضافة نص أكبر من أربعة أحرف

ملاحظة أخرى

لاحظت ان النص ينقلب !!!

يعني مثلا عند استخدام نفس الكود السابق الذي كتبته أنت ، انعكست قيمة المتغير ، بفرض أنها ليست zzzz .. لنفرض أنها qwer فعند فبعد هذا الكود تصير rewq

ممممممممممممممم

شكلي تلميذ متعب :D

#11

ولا يهمك انا بحب التلاميذ المتعبين...

التكست بالفعل ينقلب وذلك لان معالجات انتل تحفظ كل word معكوس يعنى على سبيل المثل AB تصبح BA .. هذا بالنسبه للنقطه الاولى..

إذا اردت تغير نص اكبر من اربع حروف فعليك ان تستخدم حلقه وهناك بعض الدوال

SCASB و SCASW و SCASD للبحث عن حرف حرفين او اربع حروف

STOSB و STOSW و STOSD لحفظ قيمة al او ax او eax فى الذاكره

LOADB و LOADW و LOADD لإحضار قيمه من الذاكره ووضعها فى المسجل الذى يناسب حجمها..

مثال تطبيقى

.data
alpha db "ABCDEFGHIJKLMNOPQRSTUVWXYZ",0
.code
mov edi,offset alpha
mov ecx, LENGTHOF alpha;للحصول على طول النص
mov al,'M';الحرف الذى نريد ان نبحث عنه 
cld; لتحديد إتجاه البحث هذه الداله تعنى اننا نريد ان نبحث متجهين للامام يعمنى من اول حرف لاخر حرف وليس العكس
repne scasb; هذه الداله تبحث عن الحرف 
jne quit; إذا لم تجد الحرف اقفز للنهايه 
dec edi; إذا وجدت الحرف عد خطوه للخلف لانه الحرف الذى نبحث عنه

اهم داله فى البرنامج كله هى repne scasb ومعناها هو طالما لم تجد الحرف M فى السلسله التى يؤشر عليها المسجل edi استمر فى البحث إلى ان يصبح محتوى ecx صفر, طبعاُ فى كل مره يقفزالبرنامج إلى الحرف الذى يليه يقوم بتقليص قيمة ecx , واخيراُ نتحقق من سبب توقف البحث, إما انه وجد الحرف لذلك توقف او انه لم يجد الحرف والعداد ecx اصبحت قيمته صفر..

الحاله الثانيه والتى اصبح قيمته ecx صفر نتحقق منها بالسطر jne quit طيب إذا كان ecx لا تساوى صفر إذاً البرنامج وجد الحرف الذى نبحث عنه فى هذه الحاله نعيد المؤشر خطوه للخلف ليشير إلى الحرف الدى نبحث عنه..

مثال للنوع الثانى

.data

alpha db 100 DUP(0); احجز ذاكره بسعة 100 بايت وضع قيمة 0 لكل بايت 

.code
mov edi,offset alpha
mov al,'A'
mov ecx,100
cld
;rep stosbضع القيمه التى فى المسجل  إلى الذاكره إلى ان يصبح قيمة العداد يساوى صفر

المثال للنوع الثالث ساضع لاحقاً عندما اجد فكره مفيده لإستخدامه وطريقه سهله

اما الان اكتفى بالمثالين, وطبعاُ بإستخدام هذه المجموعات الثلاثه من الدوال تستطيع ان تقوم بعمل الكثير من التغيرات فى التكست..

والسلام عليكم

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

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

#12

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

كلام جميل ، وإن كان هناك إشكال عندي في فهم بعضه

لكن كي نسير في طريق أفهمه

الحالة الاولى فيها تحديد مسبق للقيمة التي اريد إسنادها للمتغير وهذا لا أريده ، لأنه هكذا صار أقرب للثابت

الثانية رائعة لكن المشكلة العداد

طيب أقولك

الآن أنا أريد آخذ قيمة من المستخدم ثم أسندها لمتغير قمت بتعريفه في قسم .data

هذا مثال فقط كي أفهم منه الموضوع

#13

اولاً اضع إجابه مباشره على سؤالك ,

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

invoke ExitProcess,0
end start

طيب والان هذا مثال ياخذ نص من المستخدم ثم يقوم بعكسه وكتابته على الشاشه

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
pop eax
@@:
pop eax
stosb
loop @B


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

طيب هذا مثل فى الواقع هو سهل ولكنه يحتاج إلى شرح دعنا نبدا من اول البرنامج

.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 (?)

اولاً نعرف جملتين Msg1 و Msg2 بنفس الطريقه التى تعودنا عليها ثم نعرف متغيرين كل واحد منهم يحتى 50 بايت ولكن لا نعطيه قيمه مبدئيه لذلك نضعه فى .data? و ونعطى القيمه ؟ .

invoke StdOut, addr Msg1

invoke StdIn, addr myString,sizeof myString

والان نستخدم بعض دوال الAPI وهى StdOut و StdIn وتلاحظ اننا نستخد addr بدل offset ولكن النتيجه واحده, عندما نستخدم invoke نستخدم معها addr .

السطر الاول يكتب نص فى الشاشه, السطر الثانى يقراء نص من الشاشه ويضعه فى mySring ..

xor ecx,ecx
xor eax, eax

هذه الداله هى نفس الشئ إذا كتبناها هاكذى

mov ecx,0
mov eax, 0

يعنى نعطى القيمه صفر للمسجلات..

@@:
push eax
inc ecx
lodsb
test al, al
jnz @B
pop eax
pop eax
@@:
pop eax
stosb
loop @B

العلامه @@ تعنى عنوان بدون اسم, نستطيع الوصول إليه بإستخدام F@@ او B@@ الاولى تعنى اقفز للعنوان القادم الذى لا يحمل إسم يعنى العنوان @@ وB@@ تعنى العكس اى العنوان السابق

ربما يكون هذه المثال صعب شويه خصوصاً هذه الجزئه التى نقوم فيها بعكس النص, على كل حال حبيت اضعها هنا حتى ترى مثال بسيط لكيفية التعامل معى النصوص.

والسلام عليكم

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

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

#14

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

بارك الله فيك أخي أحمد

والله مجهود رائع الذي أراه

وأنا ساحاول تفصيل كل جزئية حتى أفهم وإن شاء الله بعدها أعود مرة أخرى

#15

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

واخيراُ عندما لم افلح فى إضافه صوره او ملف للمنتدى اضطريت اضعها فى عنوانى الخاص...

reverse.jpg

والسلام

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

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

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

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

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…