زبان ماشین و اسمبلی جلسه هفتم
ساير حالتهاي آدرس دهي
حالتهای آدرس دهی به اختصار در شکل زیر آمده است
حالتهاي آدرسدهي
- بلاواسطه
- ثبات
- حافظه
بلاواسطه: مقاديري هستند که در داخل دستورالعملها قرار ميگيرند.
ثبات: شامل مقاديري هستند که از يک ثبات برداشته شده و يا نتيجه دستورالعمل در يک ثبات مقصد قرار ميگيرد.
حافظه: به دو گروه مستقيم و غيرمستقيم تقسيم ميشوند.
از آدرسدهي حافظه، احتمالاً حالت مستقيم بيشترين مورد استفاده را دارد.
در برنامه منبع، اسمبلر مايکروسافت براي متمايز کردن يک عملوند غيرمستقيم از انواع ديگر عملوندها وجود حداقل يک نام ثبات در داخل کروشه را لازم ميداند.
به عنوان مثال، [bx] يک عملوند حافظه غيرمستقيم را نشان ميدهد، در صورتي که bx يک عملوند ثبات ميباشد.
حالت ثبات غيرمستقيم سادهترين حالت غيرمستقيم ميباشد. براي حالت ثبات غيرمستقيم تنها چهار قالب کد منبع وجود دارد، يعني [bx]، [si]، [dx]، [bp]، باين معني که تنها ميتوان از چهار ثبات BX، SI، DI و BP براي آدرسدهي ثبات غيرمستقيم استفاده کرده و نميتوان مقدار ديگري را به همراه اين ثباتها ذکر نمود.
در حالت ثبات غيرمستقيم، سه ثبات BX، SI و DI افست دادهها در سگمنت دادهها را نگهداري ميکنند. به عنوان مثال: عملوند [SI] در آدرس DS:SIقرار دارد که ثبات DS شامل شماره سگمنت و ثبات SI شامل افست ميباشد.
در آدرسدهي ثبات غيرمستقيم، BP به عملوندهاي واقع در پشته اشاره کرده و سه ثبات ديگر به عملوندهاي واقع در سگمنت دادهها اشاره ميکنند.
ثباتهاي BX و BP را ثباتهاي مبنا و ثباتهاي SI و DI را ثباتهاي انديس ميگويند. عملوندي به صورت [bp+6] يا [bx-4] در حالت مبنا ميباشد. عملوندي به صورت [si+20] يا [di+2] در حالت انديس ميباشد. اين دو حالت خيلي شبيه حالت ثبات غير مستقيم ميباشند.
براي به دست آوردن افست عملوند موردنظر، مقدار جابجايي به محتواي ثبات مربوط اضافه ميشود.
زماني که از يک ثبات مبنا و يک ثبات انديس استفاده ميشود، ترکيب BX/Si به اندازه يک سيکل زماني از ترکيب BX/DI سريعتر ميباشد. بهمين ترتيب، ترکيب BP/DI کمي سريعتر از ترکيب BP/SI ميباشد.
دستيابي غيرپياپي عناصر يک آرايه
در زبان اسمبلي، حافظه لازم براي يک آرايه را ميتوان با رزرو کردن يک بلوک متوالي از حافظه تخصيص داد.
مرتب سازي درجي يکي از سادهترين الگوريتمهاي مرتبسازي ميباشد. ايده اصلي اين روش اينست که تعداد position-1 عنصر اولي آرايه را به صورت مرتب شده درنظر گرفته و سپس عنصر بعدي را در مکان صحيح خود قرار دارد. اگر اين عمل را براي تمام انديسها تکرار کنيم، يک آرايه مرتب شده نتيجه خواهد شد.
اگر عناصر آرايه داراي ترتيب خاصي نباشد، در اينصورت بايستي از جستجوي پياپي استفاده نمود؛ از عنصر اول شروع کرده و عناصر آرايه را يکي يکي امتحان ميکنيم. اگر عناصر آرايه مرتب باشند در اين صورت ميتوان از الگوريتم کارآمدتر جستجوي دودويي استفاده نمود.
الگوريتم جستجوي دودويي انديس مياني آرايه را محاسبه کرده و مقدار عنصر مياني آرايه را با کليد جستجو مقايسه ميکند. اگر کليد جستجو برابر مقدار عنصر مياني آرايه باشد در اينصورت الگوريتم جستجو با موفقيت پايان مييابد. اگر کليد جستجو کوچکتر از عنصر مياني آرايه باشد، در اين صورت اگر کليد جستجو در آرايه وجود داشته باشد بايستي در نصف سمت چپي آرايه قرار داشته باشد. اگر کليد جستجو بزرگتر از مقدار عنصر مياني باشد، در اينصورت اگر کليد جستجو در آرايه وجود داشته باشد بايستي در نصف سمت راستي آرايه قرار داشته باشد.
ساختارها
يک ساختار مجموعهاي از عناصر داراي انواع مختلف که نام مشترک دارند، ميباشد؛ عناصر يک ساختار را ميتوان با استفاده از نام ساختار و نام فيلد عنصر موردنظر دستيابي نمود.
نوع PartType را ميتوان به صورت زير تعريف نمود:
Parttype STRUC
PartNbr DW?
Description DB 20 Dup(?)
Quantity DW?
تعريف نوع ساختار هميشه با دستور STRUC شروع شده و با دستور ENDS خاتمه مييابد. مانند زبانهاي سطح بالا، تعريف نوع ساختار هيچ حافظهاي را براي آن تخصيص نميدهد؛ زمان که متغيري ازنوع pARTtYPE تعريف ميشود، حافظه موردنياز براي آن تخصيص داده ميشود.
دستيابي غير پياپي عناصر يك آرايه
- برای این منظور در زبانهای سطح بالا اندیس آرایه به کار میرود
- در زبان اسمبلی میباید آرایه را در مکان متوالی ذخیره نماییم تا بتوانیم دسترسی غیر پیاپی به آن داشته باشیم
- در این حالت با محاسبه اندیس در طول آرایه و محاسبه offset میتوانیم به المان مورد نظر در آرایه دسترسی داشته باشیم
ساختارها
- ساختار مجموعه ای از عناصر است با انواع داده ها با نام مشترک
- عناصر یک ساختار را میتوان با نام مشترک و نام فیلد دستیابی کرد در پاسکال به این ساحتار فیلد گفته میشود
- میکرو اسمبلر نیز دستور field را برای تعریف ساختار در نظر گرفته است
دستكاري بيتها
عمليات منطقي
در زبان اسمبلي مقدار بولي true با مقدار بيتي يک و مقدار بولي false با مقدار بولي صفر مشخص ميشود.
تنها تفاوت بين or و xor آن است که در or، حاصل 1 or 1 يک، ولي در xor حاصل 1 xor 1 صفر ميباشد.
به عبارت ديگر دستورالعمل xor بدين معني است که وقتي يکي از طرفين برابر يک باشد، خروجي برابر يک است ولي نه زماني که هر دو طرف برابر يک هستند.
دستورالعملهاي and، or، xor و not عمليات منطقي را پيادهسازي مينمايند. فرم اين دستورالعملها عبارت است از:
And منبع، مقصد
Or منبع، مقصد
Xor منبع، مقصد
Not مقصد
دستورالعمل not هيچ فلگي را تغيير نميدهد. ولي ديگر دستورالعملهاي بولي بر روي فلگهاي ZF,SF,PF,OF,CF و AF اثر ميگذارند. فلگ رقم نقلي CF و فلگ سرريزي OF هر دو صفر ميشوند و مقدار فلگ رقم نقلي کمکي ممکن است تغيير کند، اما مقدار آن تعريف نشده است. مقادير فلگهاي توازن (PF)، علامت (SF) و صفر (ZF) بسته به مقدار حاصل عمليات يک يا صفر ميشوند
دستورالعملهاي or , and و xor همگي يکنوع عملوند را قبول ميکنند و براي اجرا به تعداد پالسهاي ساعت يکسان نياز دارند و همينطور تعداد بايتهاي کد هدف آنها برابر است.
بايد توجه داشت که هر بيتي که با 1، and شود، حاصل همان بيت اصلي خواهد بود و از طرف ديگر هر بيتي که با 0، and شود، حاصل صفر خواهد بود.
به همين دليل بيتهاي موردنظر در يک بايت يا کلمه ميتوانند به وسيله and شدن با الگويي از بيتها که داراي مقدار 1 در محلهايي که نبايد تغيير کنند و صفر در محلهايي که بايد تغيير کنند، صفر شوند
مقداردهي که معمولاً با دستورالعملهاي منطقي براي تغيير مقدار بيتها به کار ميرود، پوشش (mask)ناميده ميشود.
دستورالعمل or براي يک کردن بيتهاي موردنظر در يک بايت يا کلمه بدون تغيير بيتهاي ديگر مفيد است. بايد توجه داشت که اگر مقدار 1 با 0 يا 1 ديگر or شود، آنگاه حاصل 1 خواهد بود ولي اگر يکي از عملوندهاي 0 باشد، آنگاه نتيجه عمل or همان مقدار عملوند ديگر خواهد بود.
دستورالعمل xor بيتهاي موردنظر يک بايت يا يک کلمه را بدون تغيير بيتهاي ديگر معکوس ميکند. دليل اين امر اين است که 0 xor 1 مساوي 1 بوده و 1xor1 مساوي 0است. اين بدان معني است که هر بيتي را که به وسيله دستورالعمل xor با بيت 1 ترکيب کنيم حاصل معکوس بيت اوليه خواهد بود.
اگر بايتي که در flags قرار دارد براي ذخيره کردن هشت مقدار بولي مورد استفاده قرار گرفته باشد، آنگاه دستورالعمل or ميتوان مقادير (true) 1 را به هر بيت موردنظري نسبت دهد.
کاربردهاي ديگر دستورالعملهاي منطقي
- انجام عمليات مشخص رياضي به جاي دستورالعملهاي رياضي
- دستکاري کدهاي اسکي
- تبديل يک عدد صحيح بين 0 نا 9 به کد اسکي متناظر آن توسط دستورالعمل or
- تبديل حروف کوچک و حروف بزرگ الفبا در جدول اسکي توسط دستورالعمل xor
وظيفه دستورالعمل test آن است که فلگها را تنظيم کند.
يک کاربرد دستورالعمل test در وارسي يک بيت موردنظر از يک بايت يا کلمه ميباشد.
دستورالعمل test ميتواند براي به دست آوردن اطلاعات در مورد يک مقدار در يک ثبات مورد استفاده قرار گيرد.
دستورالعملهاي شيفت و دوران
برنامهنويس به کمک دستورالعملهاي شيفت ودوران ميتواند موقعيت بيتهاي يک کلمه يا بايت را تغيير دهد.
دستورالعملهاي شيفت، بيتهاي واقع در موقعيت داده شده به وسيله عملوند مقصد را به طرف چپ يا راست حرکت ميدهند. جهت شيفت ميتواند از آخرين کاراکتر نام دستورالعمل شيفت تشخيص داده شود –Sal و Shl شيفت به طرف چپ هستند، Sar و Shr شيفت به طرف راست ميباشند. شيفتها به دو دسته منطقي و رياضي دستهبندي ميشوند
Shl و Shr شيفتهاي منطقي بوده و Sal و Sar شيفتهاي رياضي ميباشند.
فرم کد منبع هر دستورالعمل شيفت به صورت زير ميباشند:
تعداد،مقصد S--
براي عملوند تعداد دو نگارش وجود دارد.
تک بيتي:
1 ، مقصد S--
اين نوع دستورالعمل باعث ميشود که فقط يک شيفت در عملوند مقصد صورت گيرد
چند بيتي:
Cl،مقصد S--
در اين فرم، مقدار موجود در ثبات CL به عنوان يک عدد بدون علامت تفسير ميگردد و براي دستور شيفت مشخص ميکند که مقدار موجود در عملوند مقصد را چند بيت شيفت ميدهد.
بيتهايي که از طرف چپ بيرون ميروند بدور ريخته ميشوند بغير از آخرين بيت که در فلگ رقم نقلي CF ذخيره ميگردد.
بسته به آخرين مقداري که در عملوند مقصد قرار ميگيرد، فلگهاي علامت (SF)، صفر (ZF) و توازن (PF) تعيين ميگردند. فلگ سرريزي براي يک شيفت چندبيتي تعريف نشده باقي ميماند، اما براي يک شيفت تکبيتي چنانچه بيت علامت حاصل همانند بيت علامت مقدار اوليه عملوند مقصد باشد، برابر صفر شده و چنانچه متفاوت باشند، برابر يک خواهد گرديد. فلگ رقم نقلي کمکي AF تعريف نشده نميباشد.
همانند شيفت به طرف چپ، مقادير SF، ZF و PF به نتيجه عمليات بستگي خواهند داشت و AF تعريف نشده خواهد بود. فلگ سرريزي OFدر يک شيفت چندبيتي تعريف نشده خواهد بود.
براي يک شيفت تکبيتي منطقي به طرف راست (Shr)، چنانچه بيت علامت حاصل همانند بيت علامت مقدار اوليه عملوند مقصد باشد، در اينصورت فلگ سرريزي OF برابر صفر شده و در غير اينصورت برابر يک خواهد شد. در شيفت رياضي به طرف راست چندبيتي (Sar)، OF هميشه صفر ميگردد.
دستورالعملهاي شيفت از دستورالعملهاي پايهاي هستند، اما داراي کاربردهاي زيادي ميباشند.
وقتي قرار باشد که عددي در دو ضرب شود، يک شيفت تکبيتي به طرف چپ عدد اوليه ميتوان حاصلضرب صحيح را در اختيار بگذارد.
يک شيفت تکبيتي به طرف چپ عملوندهاي علامتدار را نيز دو برابر ميکند.
يک عمل شيفت تکبيتي به طرف راست ميتواند به صورت مؤثري براي تقسيم کردن يک عملوند بدون علامت بر دو، مورد استفاده قرار گيرد.
شيفت به طرف راست براي اعداد منفي، به طور کامل همانند تقسيم بر دو نيست.
اگر مقسوم يک عدد فرد منفي باشد آنگاه خارج قسمت به صورت نقصاني گرد خواهد شد.
دستورالعملهاي دوران خيلي شبيه دستورالعملهاي شيفت هستند. در دستورالعملهاي شيفت، بيتها از يک طرف شيفت داده شده و به دور ريخته ميشوند، در حاليکه جاهاي خالي از طرف ديگر با صفر پر ميشوند. ولي در دستورالعملهاي دوران، بيتهايي که از يک طرف به بيرون شيفت داده ميشوند، از طرف ديگر فضاهاي خالي را پر ميکنند.
يک دستورالعمل دوران تکبيني داراي فرم زير ميباشند:
I rotate 1bit; ، مقصد r--
چندبيتي:
CL rotate number of bits given by CL; ، مقصد r--
در دستورالعملهاي rol (rotate left، دوران به طرف چپ) و ror (rotate right، دوران به طرف راست) ميتوان از عملوندهاي بايت يا کلمه در ثبات يا حافظه استفاده کرد.
آخرين بيت که به طرف ديگر عملوند کپي ميشود در فلگ رقم نقلي CF نيز منعکس ميگردد؛ اين «آخرين بيت» تنها براي دوران حالت تکبيتي ميباشد. فلگ سرريزي OF تنها فلگ ديگري است که از دستورالعملهاي دوران اثر ميپذيرد. در دورانهاي چندبيتي فلگ سرريزي تعريف نشده است.
مثال:
بعنوان مثال فرض کنيد ثبات DX حاوي مقدار D25E است و دستورالعمل
Rol dl,1
اجرا ميشود، اجرا به صورت دودويي به شکل زير است:
و نتيجه در ثبات DX برابر عدد A4BD است. فلگ رقم نقلي برابر يک ميگردد، زيرا يک بيت 1 از انتهاب چپ به طرف راست رفته است.
يک جفت دستورالعمل دوران ديگر وجود دارند که هر کدام به گونهاي عمل ميکنند که فلگ رقم نقلي CF قسمتي از عملوند مقصد است:
Rcl , rcr
دستورالعملهاي دوران با استفاده از فلگ رقم نقلي که به طور مشخص CF را تغيير ميدهند بر روي OFنيز اثر ميگذارند ولي هيچ تغييري در فلگهاي ديگر نميدهند.
تبديل يک رشته اسکي به يک عدد صحيح مکمل دو
ماکروي atoi به منظور پويش ناحيهاي از حافظه که حاوي يک رشته اسکي که نشاندهنده يک عدد صحيح است به کار برده شده است وحاصل آن يک عدد صحيح مکمل دو در ثبات AX است.
اين ماکرو ميتواند به مجموعه دستورالعملهاي زير بسط پيدا کند:
Push si ;;save SI
Lea si,source ;;source address to SI
Call atoi_proc ;;call procedure
Pop si ;;restore SI
اين دستورالعملها براي ارسال آفست رشته اسکي به روال atoi_proc از ثبات SI استفاده ميکنند. مقدار اوليه ثبات SI در پشته ذخيره ميگردد تا برنامهنويس بتواند از اين ثبات به منظورهاي ديگري استفاده نمايد. شناسه source کاربر و نه اسم source، در ماکروي بسط يافته مورد استفاده قرار ميگيرد.
دستورالعملهاي شيفت و دوران
- در زبان اسمبلی هر شیفت به منعنای چرخش بیتها درون یک رجیستر است
- هر چرخش به چپ معادل ضرب در عدد 2 است
- هر چرخش به راست معادل تقسیم عدد به 2 است
- عمل دوران باعث میشود بیتی که از یک طرف خارج میشود از سمت دیگر وارد شود
- دستورات SHL , SHR شیفتهای منطقی هستند
- دستورات SAL , SAR شیفتهای ریاضی هستند
تبديل يك رشته اسكي به يك عدد صحيح مكمل 2
- در زبان اسمبلی ماکروی itoa برا ی این تبدیل در نظر گرفته شده است
استفاده از این ماکرو به این دلیل ضرورت دارد که همواره اعدادی که از صفحه کلید دریافت میشوند بصورت کارکتر بوده و برای ذخیره در رجیسترها باید بصورت عدد مکمل 2 در آیند
