|
:: نائب المشرف العام ::
تاريخ التسجيل: Jun 2009
الدولة: القاهرة - مصر
المشاركات: 11,652
|
|
نشاط [ ماجد عباس محمد ]
قوة السمعة:
|
|
04-07-2018, 09:39 AM
المشاركة 59
|
|
الأكواد العشرة
الأكواد العشرة
تنقسم الأكواد العشر لثلاث مجموعات هى الشروط و الدورات و الانتقال
الشروط:
الأمر IF
الأول هو ما سبق شرحه IF و نعيد شرحه هنا أولا بالأسيمبلى كان فى صورة JB أو JNB وهما القفز لو بت =1 أو = صفر ولكن عموما تحتاج مقارنة رقمين لذا نستخدم معها الأمر CJNE وهو اختصار Compare and Jump if Not Equal وهى تقارن بين المراكم A و قيمة مباشرة أو محتوى ذاكرة مع المراكم أو محتوى مسجل مع المراكم أو باعتبار مسجل من R0,R1 حامل عنوان فيقارن المراكم بالذاكرة التى يشير إليها هذا المسجل أو مسجل مع قيمة مباشرة مثلا سنقارن محتوى المسجل R7 بالقيمة المباشرة 60 هيكسا و ننتقل لو مختلفين إلى Not_Eq. ما يحدث حقا هو طرح القيمة 60 هيكسا من محتوى R7 و بالتالى لو 60 أكبر ستسبب Carry =1 و إلا سيكون Carry = Zero و يمكن التحقق بالأمر JC أى قفز لو Carry =1
كود:
CJNE R7, # 60H, NOT_EQ ; . . . . . . . . ;R7 = 60H.
Code if equal
sjmp Finish
NOT_EQ: JC REQ_LOW ; IF R7 < 60H.
Some Code for R7 > 60H. ; . . . . . . . . ;R7 > 60H.
sjmp Finish
REQ_LOW: code for R7 < 60H.
Finish:
لو تريد أن تقارن شيء آخر ستضع قيمة فى R7 و الثانية فى الأمر المباشر و هكذا أى ستحتاج لأوامر MOV لتعديل القيم
نفس الشيء بالبيزك و مثال للمقارنة على التساوى فقط فى التالى أو يمكنك التعديل بلا يساوى أو اكبر من أو أصغر من أو ما تشاء من شروط متعددة
كود:
If Sw1 = 1 then
Goto SW2test
Else
LEDs = 254
End If
كما يمكنك أن تجعلها متداخلة Nested أى أكثر من أمر داخل بعض هكذا
كود:
If PORT1 = 1 then ; Level 1
Goto SW2test
Else IF PORT2 = 1 THEN ; Level 2
LEDs = 254
ELSE ; Level 2
LEDs= 255
Else ; Level 1
LEDs=255
End If
لاحظ هنا نقطة مهمة IF الأولى استفسرت عن شيء ما وهو PORT1 بينما Else IF التالية استفسرت عن شيء آخر تماما وهو PORT2 وهذه قيمة هذا الأمر ولو عدنا للغة الأسيمبلى سنجد أن هذا الأمر سيضع PORT1 أولا فى المراكم A ثم يقارنها بالقيمة 1 و بعد ذلك يضع القيمة PORT2 فى المراكم ليقارنها بالقيمة الجديدة (و إن تساوت ظاهريا) 1 وفى كل مرة نستخدم أمر MOV قبل الاختبار
نقطة هامة أخرى، أين تضع End If يعتمد على المترجم فالمترجم باسكوم يعتمد Elseif و يعتبرها امتداد للأولى (وهذا من سمات لغة البيزك المرئى الأصلية للحاسبات) و من ثم تفاضل بين عديد من الخيارات و متى تحقق أحدها خرجت من الدورة ولذا تحتاج End if واحدة فقط فى آخرها و يمكنك وضع IF أخرى متداخلة حيث تشاء لتتمكن من فحص خيارات أخرى متى شئت و هذا يصعب فى ميكروإلكترونيكا فمثلا
كود:
If a = b then '…...1
Led0 = 1
elseif c=d then '…....2
Led1=1
elseif porta = 5 then '…......3
if a= 8 then
Print Porta = 5 and a=8
elseif g=7 then
Motor1 = 1
else
Motor 1 =0
end if
else if Portc =0 '….....4
Led3=1
else ' ….....5
Led4 = 0
end if
سنلاحظ هنا أن الشروط 1،2،3،4،5 تبادلية فإن تحقق 1 ينفذ الأمر Led0 = 1 ثم تخرج و إلا يفحص 2 و هكذا، بهذا فالشروط باللون الأحمر لن تفحص إلا لو لم تتحقق الشروط السابقة أولا ثم تحقق الشرط porta = 5 و عندها نتحقق كما لو ان كل أمر من الأحمر تعنى لو porta = 5 مع a= 8 و قد تكتب هكذا
(a= 8) AND (porta = 5)
إلا أننا وفرنا تنفيذ أمر AND فى كل تساؤل.
ميكروإلكترونيكا لا تعتمد elseif و تعتمد بدلا عنه else if بمسافة تفصل بينهما فتعتبر if التالية جديدة و تتطلب End If خاصة نفس فكرة أقواس السى وهذا يجعل الأمور معقدة و مربكة .
مما سبق أيضا نستنتج أن ترتيب الأوامر يعطى أولوية الاختبار فقد يسبب تساؤل عن أمر ما أقل أهمية فى عدم فحص أمر آخر أكثر أهمية .
و لنكتبه بلغة C
كود:
if (PORT1=1) {
goto SW2test ;
}
else if (PORT2) {
LEDs = 254 ;
}
else {
LEDs=255;
}
الآن علمنا أن هناك MOV زائدة فى كل أمر حتى لو كان المتغير لم يتغير لكن تريد مقارنته بعدة قيم ولا داعى لنقله كل مرة للمراكم A لنقارنه ، فهذا سيوفر خانة ذاكرة فى كل اختبار و يزيد سرعة الاستجابة ، لذا كان الأمر الثانى.
الأمر Select case أو switch
وهو الثانى ، فكما رأينا الحاجة أم الاختراع فقد وضع هذا الأمر لمقارنة قيمة واحدة مقابل عدد كبير من الاحتمالات، لذا فهذا الأمر بالأسيمبلى سيكون ذات التعليمات السابقة و ستكرر الأمر CJNE عدة مرات كل مرة بقيمة اختبار أخرى و لكن لن تستخدم JC إلا لو احتجت لها و ستضع القيمة التى تختبرها مرة واحدة فقط فى المراكم وهى فى المثال التالى قيمة reg و بعد ذلك تكرر CJNE حسب ما تريد، أى ستوفر أمر MOV مع كل مقارنة.
و فى البيزك / باسكوم
كود:
select case reg
case 0
opmode = 0
case 1,2,6
opmode = 1
case 5 TO 7
opmode = 2
Case > 9 : Print “Too High”
Case else : PRINT “NOT Valid”
end select
السطر الأول نجد هو المتغير تحت الاختبار و من ثم يوضع أول الأمر فى المراكم ثم يقارن عدة مرات بعد ذلك. قد يكون أى متغير مثل PORT0 أو أى شيء تسميه أو حتى معادلة يجب حلها أولا مثل select case x*y/z
المهم أنها رقم صحيح (قيد بسبب الميكرو لكن فى الحاسبات الشخصية تكون أى شيء) أو قد يكون نصا أو حرف.
هذا المترجم يسمح من لغة البيزك الأصلية بكلمة TO لتحديد مدى "من إلى" كما يسمح بتعدد القيم 1,2,6 و بالعلاقات النسبية أكبر من أو أصغر من أو اكبر من و يساوى أو أصغر من و يساوى
لاحظ أنه لو تطابق المتغير مع أول شرط ستنفذ الأوامر المرتبطة به بكاملها (واحد أو أكثر) ثم يخرج آليا من الشرط ولا تختبر باقى الحالات. لو لم يتطابق فسيقارن التالى وهكذا
ميكروإلكترونيكا تستخدم الصيغة ذاتها مع تعديل طفيف
كود:
select case reg
case 0
opmode = 0
case 1,2,3,4
opmode = 1
case 5,6,7
opmode = 2
end select
وهو أنها لم تتبنى كلمة TO باعتبار أن القيم المتعددة قد تغنى لكن لن تكون مثلا مثل من 100 إلى 200 و لم تتبنى المقارنات > < >= <= أيضا.
بلغة السى نجدها
كود:
switch (phase) {
case 0: Lo(); break;
case 1: Mid(); break;
case 2: Hi(); break;
default: Message("Invalid state!");
}
حيث phase هى المتغير تحت المقارنة ثم تلى القيمة الأولى وهى صفر فينفذ الأمر لو متطابق ولا ينفذه لو غير مطابق و فى كلتا الحالتين سينتقل لاختبار القيمة التالية،(لماذا؟؟) لذا وجب وضع الأمر break حتى يخرج من الدورة عند تحقق الشرط !!!
لاحظ أيضا أنك لا تستطيع استخدام مدى من .. إلى .. ولا أكثر من قيمة 1,2,3,4 ولا نسب أكبر و أصغر الخ. رقم و فقط و بسبب ذلك قد تضطر لاستخدام أمر IF بدلا منها !!!!! أو تفضل البيزك مثلى
المرة القادمة إن شاء الله ندرس الدورات
|