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

تفسير نواتج

بدأه ليااال في 13 ديسمبر 2010 · 5 رد · 872 مشاهدة · في أرشيف قسم الـــ Assembly
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

محتاجة ضروري شرح الاجابة بالتفصيل

post-237276-001909600 1292233047_thumb.j

المرفقات
Test2-21.jpg

تم تعديل هذه المشاركة بواسطة ليااال في 13 ديسمبر 2010 في 12:37

#2

الأسئلة مجاب عنها :|

فما الذي تحتاجينه، شرح تنفيذ التعليمات أو الغرض منها ؟؟

Do as I say, not as I do

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

#3

محتاجة شرح تنفيذ تعليمات

#4

كما تشائين..

الطلب 1:

يسأل عن تعليمة واحدة تقوم بجعل قيمة البتات من 5 حتى 11 تساوي 1 في المسجل BX وتترك باقي البتات الأساسية في المسجل بدون تغيير فإن كانت 0 تبقى 0 وإن كانت 1 تبقى 1 وهذا ينطبق على البتات من 0 حتى 4 ومن 12 حتى 15 (ليشكل 16 بت ككل وهو طول المسجل BX)

التعليمة المقترحة في الحل:

or bx, 0fe0h

القيمة 0FE0h تساوي بالتمثيل الثنائي (111111100000b) .. ستلاحظين فيها أن البتات ذوات الترتيب 5 حتى 11 جميعها تساوي 1 بينما البقية تساوي 0 (البتات من 12 حتى 15 لا تظهر لأنها تساوي 0 على يسار الرقم فهي مهملة لكنها بالأساس موجودة)

لماذا هذه القيمة؟ التعليمة OR تعمل كالتالي:

0 or 0 = 0

1 or 0 = 1

0 or 1 = 1

1 or 1 = 1

نلاحظ أن الحيادي في عملية OR هو الصفر، فمهما كانت قيمة البت الأساسية فإنها لا تتغير في الناتج إن تم تنفيذ OR مع 0.

ونلاحظ أنه مهما كانت قيمة البت الأساسية فإنها تصبح 1 إن تم تنفيذ OR مع 1، وهذا المطلوب من السؤال.

لنأخذ مثال:

<pre>

BX = 50 = 0000000000110010b

OR 0FE0h = 0000111111100000b

----------------------------

0000111111110010b

</pre>

وهو المطلوب، حافظنا على البتات من 0 حتى 4 ومن 12 حتى 15 وقلبنا قيمة البتات من 5 حتى 11.

هذا السؤال مشابه للعديد من الأسئلة التي شرحتها لك من قبل.

سأتركه في مشاركة منفصلة لسهولة الإيضاح.

1

Do as I say, not as I do

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

#5

شكرا الله يوفقك

#6

الطلب الثاني:

cdq
idiv	edi

يجب استخدام تعليمة CDQ (أو CDW) قبل عملية القسمة لتجنب الوقوع في أي مشكلة نتيجة كون الرقم و/أو المقسوم عليه كبير أو صغير .. أو كونه مؤشر أو غير مؤشر.

ويفضل استخدامها على الدوام فهي إن لم تنفع فلن تضر.

تعليمة idiv ستقوم بحساب ناتج قسمة eax/edi

يتم تخزين الجزء الصحيح للناتج في EAX

يتم تخزين باقي القسمة في EDX

تكون الصيغة العامة:

Number = EAX*EDI+EDX

Dividend = EAX/EDI

Remainder = EDX

الطلب الثالث:

push	0FFFFFFFFh
popfd

القيمة 0FFFFFFFFh تساوي ثنائياً القيمة 11111111111111111111111111111111b وكما نرى جميع البتات تحمل القيمة 1 (وهو ما يطلبه السؤال)

التعليمة popfd تقوم بسحب القيمة الموجودة في قمة المكدس وتضعها في مسجل الرايات الموسع eflags

إذاً للتعديل على مسجل الرايات الموسّع نقوم بدفع القيمة التي نريد وضعها فيه إلى المكدس أولاً باستخدام PUSH value ومن ثم نقوم بسحبها من المكدس وتحميلها في مسجل الرايات الموسع باستخدام POPFD

الطلب الرابع:

shr	cx, 1
rcr	dx, 1

لنفرض القيم التالية:

CX = 179 = 10110011

DX = 25 = 00011001

CX:DX = 00011001:10110011

من المعروف أن تنفيذ SHR بمقدار 1 يماثل قسمة الرقم على 2

إن قيمة CX:DX هنا تساوي 6579 أي 0001100110110011

وبقسمة الرقم على 2 نحصل على 3289.5 أي 0000110011011001.1

يجدر بي الإشارة هنا إلى أني أعتقد بوجود خطأ في التعليمات الموضحة في الصورة (والله أعلى وأعلم)، حيث يجب أن تكون:

shr dx, 1
rcr cx, 1

حيث أن إزاحة DX بمقدار 1 إلى اليمين سيعطي 00001100 وتصبح قيمة راية الحمل CF = 1

وتدوير CX بمقدار 1 إلى اليمين مع الحمل سيعطي 11011001 وتصبح قيمة راية الحمل CF = 1

ومن ثم بضم القيمتين وفقاً للطريقة المبينة أعلاه سيكون لدينا: 00001100:11011001

وهذا يساوي النتيجة التي حصلنا عليها أعلاه بعد تنفيذ القسمة على 2.

الطلب الخامس:

movzx	esi, bl
shr	esi, 4

والمطلوب وضع ناتج قسمة BX/16 في المسجل ESI.

التعليمة الأولى ستقوم بنسخ قيمة BL إلى البايت الأقل أهمية في ESI وتقوم بتصفير باقي البايتات (فكما تلاحظين BL طولها بايت واحد بينما ESI طولها 4 بايت ولا يمكن النسخ بهذه الطريقة باستخدام تعليمة MOV التقليدية لذلك نستخدم MOVZX وقد ترد أيضاً MOVSX)

كما نعلم فإن الإزاحة بمقدار 1 إلى اليمين يماثل القسمة على 2

والإزاحة بمقدار 2 يماثل القسمة على 4

والإزاحة بمقدار 3 يماثل القسمة على 8

والإزاحة بمقدار 4 يماثل القسمة على 16

والصيغة العامة: القسمة على عدد X من مضاعفات 2 يماثل الإزاحة بمقدار mimetex.cgi?2^{shift}=X حيث shift هو مقدار الإزاحة.

الطلب السادس:

pop	eax
call	writeint

المطلوب إظهار آخر كلمتين (2 word) في المكدس على الشاشة.

هذا يعني 4 بايتات من أعلى المكدس.

إذاً سنقوم بسحب البايتات الأربع إلى مسجل بطول 32بت مثل EAX باستخدام تعليمة POP

ومن ثم سنقوم بطباعة القيمة على الشاشة باستدعاء الدالة WRITEINT من مكتبة Irvine.

سيحتاج الأمر ملفي Irvine32.inc و Irvine32.lib، لكن هذا غير مهم الآن وأذكره فقط للتوضيح.

1

Do as I say, not as I do

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

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