محتاجة ضروري شرح الاجابة بالتفصيل
تفسير نواتج
الأسئلة مجاب عنها :|
فما الذي تحتاجينه، شرح تنفيذ التعليمات أو الغرض منها ؟؟
Do as I say, not as I do
We are Anonymous. We are Legion. We don't forgive. We don't forget
محتاجة شرح تنفيذ تعليمات
كما تشائين..
الطلب 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.
هذا السؤال مشابه للعديد من الأسئلة التي شرحتها لك من قبل.
سأتركه في مشاركة منفصلة لسهولة الإيضاح.
Do as I say, not as I do
We are Anonymous. We are Legion. We don't forgive. We don't forget
شكرا الله يوفقك
الطلب الثاني:
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 يماثل الإزاحة بمقدار حيث shift هو مقدار الإزاحة.
الطلب السادس:
pop eax call writeint
المطلوب إظهار آخر كلمتين (2 word) في المكدس على الشاشة.
هذا يعني 4 بايتات من أعلى المكدس.
إذاً سنقوم بسحب البايتات الأربع إلى مسجل بطول 32بت مثل EAX باستخدام تعليمة POP
ومن ثم سنقوم بطباعة القيمة على الشاشة باستدعاء الدالة WRITEINT من مكتبة Irvine.
سيحتاج الأمر ملفي Irvine32.inc و Irvine32.lib، لكن هذا غير مهم الآن وأذكره فقط للتوضيح.
Do as I say, not as I do
We are Anonymous. We are Legion. We don't forgive. We don't forget