فصل دهم

ساير حالتهاي آدرس دهي

 

دستورالعمل int و جدول بردار وقفه‌ها

 

بعضي مواقع از فراخواني معمولي روال‌ها استفاده مي‌شود. ولي DOS و بسياري از سيستم‌عامل‌هاي ديگر از نوع بخصوص فراخواني روال استفاده مي‌کنند؛ يک وقفه نرم‌افزاري که بعضي مواقع آن را يک تله يا يک استثناء مي‌گويند.

براي فعال کردن يک وقفه مي‌توان از دستورالعمل int استفاده نمود.

بعلاوه، بعضي وقفه‌هاي توسط خود سخت‌افزار PC توليد مي‌شوند.

 

يک وقفه عملاً داراي يک پردازنده وقفه مي‌باشد که بلوکي از کد مي‌باشد که تقريباً مانند يک روال معمولي مي‌باشد. يک پردازنده وقفه به جاي دستورالعمل Call توسط دستورالعمل int فراخواني مي‌شود. براي برگشتن از يک پردازنده وقفه، به جاي استفاده از دستورالعمل ret براي يک روال معمولي از دستورالعمل (interrupt return) iret استفاده مي‌شود.

 

دستورالعمل Int‌داراي قالب زير است:

Int interrupt_type

 

که Interrupt_type‌برابر يک عدد صحيح از 0 تا 255 مي‌باشد.

وقتي اين دستورالعمل اجرا مي‌شود، ابتدا محتواي ثبات نشانه‌ها را روي پشته اضافه کرده و سپس نشانه‌هاي IF (نشانه فعال‌سازي وقفه) و TF (نشانه تله) خاموش مي‌گردند.

 

دستورالعمل برگشت از وقفه يعني iret بدون عملوند مي‌باشد.

اين دستورالعمل ابتدا مانند يک دستورالعمل برگشت دور عمل مي‌کند يعني اينکه ثبات‌هاي IP و CS را از روي پشته برداشته و سپس مقادي رنشانه‌ها را از روي پشته برمي‌دارد. در نتيجه تمام نشانه‌ها برابر مقاديري که توسط دستورالعمل Int روي پشته ذخيره شده بودند، مي‌گردد.

 

معمولاً دستورالعمل into بعد از دستورالعملي که احتمال به وجود آمدن حالت سرريزي وجود داشته باشد، به کار مي‌رود.

بعضي از اين وقفه‌هاي براي پردازش وقفه‌هاي سخت‌افزاري به کار مي‌روند.

 

درخواست توابع DOS

 

تمام توابع فراخواني شده توسط int 21h يک پردازنده وقفه معيني را فراخواني مي‌کنند. تابع مورد نظر با قرار دادن شماره تابع مربوطه در ثبات AH انتخاب مي‌شود.

با توجه به اينکه تمام نشانه‌ها توسط دستورالعمل‌هاي int و iret روي پشته حفظ مي‌گردند، مقادير نشانه‌ها تغيير پيدا نمي‌کنند.

ورودي/خروجي فايل‌هاي پياپي با استفاده از DOS

اکثر توابع DOS که از طريق int 21h فراخواني مي‌شوند، در مورد عمليات روي فايل‌هاي ديسک مي‌باشند. از جمله توابع زير مي‌باشند.

تشکيل دادن يک فايل جديد

باز کردن يک فايل

بستن يک فايل

خواندن داده از يک فايل

نوشتن داده روي يک فايل

حذف کردن يک فايل

 

براي شناسايي يک فايل، اکثر توابع DOS از يک عدد 16 بيتي به نام هندل فايل استفاده مي‌کنند. در زمان باز کردن يک فايل، نام به سيستم DOS انتقال يافته و هندل فايل مزبور براي استفاده‌هاي آتي توسط DOS برگردانده مي‌شود. براي خواندن از فايل، نوشتن روي يک فايل يا بستن يک فايل، هندل فايل موردنظر به سيستم DOS انتقال مي‌يابد.

ثبات AL شامل اطلاعاتي در مورد نحوه باز کردن فايل موردنظر مي‌باشد:

چهار بيت پائيني شامل يک عدد بدون علامت به شرح زير مي‌باشد.

 

0000 براي باز کردن فايل به صورت فقط خواندن

0001 براي باز کردن فايل به صورت فقط نوشتن

0010 براي باز کردن فايل به صورت خواندن و نوشتن

 

براي يک محيط ساده PC، مي‌توان ثبات AL را به صورت زير مقداردهي کرد:

0 براي خواندن از فايل

1 براي نوشتن روي فايل

2 براي خواندن و نوشتن فايل

 

 

کدهاي خطا:

 

کدهايي براي وجود داشتن يک مقدار نادرست در ثابت AL

وجود نداشتن يک فايل

تعداد فايل‌هاي باز بيش از اندازه مجاز بودن

 

 

ورودي/خروجي بدون سيستم‌عامل (با استفاده از دستورالعمل‌هاي int و out)

در اين دور مورد استفاده از روال‌ها و توابع DOS براي انجام عمليات ورودي و خروجي تأکيد شده است. باين ترتيب برنامه‌ها مي‌توانند از يک سيستم کامپيوتري به سيستم ديگري تا اندازه‌اي قابل حمل باشند با وجود اين، در پائين‌ترين سطح اجرا، ورودي و خروجي بايستي با استفاده از دستورالعمل‌هاي In‌و out‌ صورت گيرد.

منبع دستورالعمل out بايستي ثبات AX (يک کلمه) يا AL (يک بايت) باشد. بهمين ترتيب، مقصد دستورالعمل in بايستي برابر ثبات AX يا AL باشد.

 

از درگاه کنترل چاپگر براي هدايت عمليات مختلف چاپگر استفاده مي‌شود.

بيت 0 معمولاً برابربا 0 مي‌باشد. ولي براي مطلع ساختن چاپگر از اينکه يک بايت داده با آن ارسال شده است، اين بيت براي مدت زمان کوتاهي برابر 1 قرار داده مي‌شود.

 

قبل از فرستادن يک کاراکتر به چاپگر، برنامه بايستي اطمينان حاصل کند که چاپگر مشغول نمي‌باشد. اينکار با خواندن يک بايت از درگاه وضعيت چاپگر و کنترل بيت 7 وضعيت را نشان مي‌أهد، صورت مي‌گيرد. اين عمل تا زماني که اين بيت برابر 0 مي‌باشد تکرار مي‌گردد.

به محض آزاد شدن چاپگر، کاراکتر موردنظر در داخل ثبات AL و آدرس درگاه داده‌ها در داخل ثبات DX‌قرار گرفته و دستورالعمل out بايت مربوط را ارسال مي‌کند.

يک PC همچنين مي‌تواند از طريق درگاه‌هاي ورودي/خروجي سريال با دستگاه‌هاي جانبي ارتباط برقرار نمايد. تفاوت بين ارتباط موازي و سريال اينست که در ارتباط موازي هشت بيت به طور همزمان از طريق هشت سيم منتقل مي‌شود، در حالي که در ارتباط سريال، بيت‌هاي يک بايت باضافه بيت‌هاي شروع و توقف به صورت يک بيت در هر زمان از طريق يک سيم منتقل مي‌شوند.

 

پردازش اسمبلي

اسمبلي دوگذري

وظيفه يک اسمبلر آن است که کد منبع زبان اسمبلي را به کد هدف تبديل نمايد.

مايکرو اسمبلر مايکروسافت يک اسمبلر دوگذري است. اين به آن معني است که يک برنامه منبع زبان اسمبلي دوبار به وسيله MASM پويش مي‌شود تا فايل کد هدف آن ايجاد شود. مي‌توان يک اسمبلر را به صورت يک گذري طرح کرد و بعضي اسمبلرها برنامه منبع را سه بار يا بيشتر پويش مي‌کنند اما بيشتر اسمبلرها از دو گذر بهره مي‌برند.

يک مزيت نوشتن برنامه به زبان اسمبلي نسبت به زبان ماشين آن است که در آن مي‌توان از شناسه‌ها يا نمادها براي رجوع به داده‌ها در سگمنت داده و دستورالعمل‌ها در سگمنت کد استفاده نمود.

يک وظيفه اسمبلر آن است که يک جدول علائم در ارتباط با هر شناسه با مشخصه‌هاي مختلف را تشکيل داده و آن را حفظ کند.

يک مشخصه برابر نوع يک نماد است.

اين انواع شامل موارد زير مي‌باشد:

برچسب داده‌ها و دستورالعمل‌ها

نمادهايي که مساوي ثبات‌ها درنظر گرفته شده‌اند

اسامي روال‌ها

اسامي ماکروها

اسامي سگمنت‌ها

 

چنانچه نمادي مربوط به داده يا دستورالعمل باشد، آنگاه موقعيت آن در جدول علائم وارد مي‌شود. اسمبلر داراي يک شمارنده موقعيت است که اين مقدار را محاسبه مي‌کند. معمولاً در يک اسمبلر شمارنده موقعيت در ابتداي برنامه يا در ابتداي بخش‌هاي مهمي از برنامه، صفر مي‌گردد.

 

چنانچه اسمبلر بخواهد از اين قاعده پيروي کند که داده‌ها قبل از دستورالعمل‌هاي اجرايي بايد مشخص باشند، آنگاه جدول علائم ورودي‌هايي را براي داده‌ها در حين گذر اول در نظر مي‌گيرد. ممکن است بدين ترتيب به نظر برسد که اسمبلي يک گذري ساده است. البته در چنين مواردي پرش به دستورالعمل‌هاي اجرايي جلوتر با مشکلاتي مواجه خواهد شد.

اسمبلرهاي مختلف مقدار کار متفاوتي را در حين گذر اول انجام دهند. بعضي براي ايجاد جدول علائم فقط از شمارنده موقعيت استفاده مي‌نمايند. بعضي ديگر در حين گذر اول هم جدول علائم را ايجاد مي‌کنند و هم کد هدف تقريباً کاملي را توليد مي‌نمايند. ماکرو اسمبلر مايکروسافت جزء دسته دوم است.

 

وظيفه اصلي يک اسمبلر، توليد کد هدف است. البته اسمبلرها کارهاي بسيار زياد ديگري را نيز انجام مي‌دهند. يک وظيفه، ذخيره کردن فضا است.

اسمبلر علاوه بر ذخيره کردن حافظه مي‌تواند فضاي ذخيره شده را با مقادير معيني مقداردهي کند.

 

اکثر اسمبلرها مي‌توانند فايل ليست را توليد کنند، اين فايل کد منبع اصلي را بهمراه کد هدف مربوطه عرضه مي‌کند. مسئوليت ديگر يک اسمبلر آن است که وقتي اشتباهي در کد منبع وجود دارد پيغام‌هاي خطا را توليد کند. اسمبلرهاي اوليه فقط براي هر اشتباه فقط شماره خط و کدخطا را نمايش مي‌دادند. نسل‌هاي بعدي اسمبلرها يک صفحه مجزا با شماره خط و پيغام خطا ايجاد مي‌کردند. اکثر اسمبلرها مي‌توانند پيغام خطا را در فايل ليست در محلي که خطا وجود دارد قرار دهند. ماکرو اسمبلر مايکروسافت پيغام خطا را در فايل ليست قرار مي‌دهد و آنها را برروي صفحه نمايش نيز نمايش مي‌دهد.

 

علاوه بر ليستي که برنامه منبع و کد هدف را نشان مي‌دهد، اغلب اسمبلرها مي‌توانند ليست علائم مورد استفاده در برنامه را نيز توليد نمايند. چنين ليستي ممکن است اطلاعاتي را درباره مشخصه هر نماد و همينطور جدول ارجاع را که مشخص کننده خطي است که يک نماد در آنجا تعريف شده است و خطوطي که به آن رجوع کرده‌اند، در برگيرد.

ماکرو اسمبلر مايکروسافت يک اسمبل دوگذري است. اين اسمبلر قادر است کدهاي هدفي را ايجاد کند که به محلهايي در فايلهاي ديگر رجوع نمايند و همينطور حاوي علائمي باشد که قابل جابجايي مي‌باشند. برنامه کمکي LINK در MS-DOS فايلهايي را که داراي کدهاي هدف مجزا هستند دريکديگر ترکيب کرده و رجوع به فايل‌هاي ديگر را ممکن مي‌سازد. لودر MS-DOS که به طور خودکار با وارد کردن اسم فايل برنامه اجرايي صدا مي‌شود، قسمت نهايي کار ترجمه فايل را انجام مي‌دهد، يعني قبل از آماده‌سازي اجرا آن را در درون حافظه بار مي‌کند.

 

چند دستور اسمبلر

هر کدام از دستورات اسمبلر از اسمبلر مي‌خواهد که وظيفه خاصي را انجام دهد.

دستور اسمبلر ASSUME‌داراي فرم زير است:

ASSUME  segment_register:segment_name,…

 

که segment_name مي‌توان هرکدام از ثبات‌ها ES,DS,CS يا SS بوده و SEGMENT_NAME‌برچسب دستور اسمبلر SEGMENT‌است.

 

چنانچه MASM به علامتي برخورد نمايد که در سگمنتي که اسم آن در دستور اسمبلر ASSUME معرفي شده است، وجود نداشته بشاد، آنگاه اسمبلر يک پيغام خطا توليد خواهد نمود.

يک برنامه کد منبع زبان اسمبلي ممکن است داراي چندين دستور اسمبلر ASSUME باشد. اين مطلب بخصوص در مورد برنامه‌هاي طولاني که حاوي روال‌هاي بسياري هستند صحيح است. همانطور که دستورات پويش مي‌شوند، اسمبلر از جديدترين اطلاعاتي که به ثبات سگمنت نسبت داده شده است، استفاده مي‌کند.

گاهي اوقات لازم است که از MASM خواسته شود که از فرض قبلي در مورد ثبات سگمنت صرفنظر کند و هيچ فرض جديدي هم در نظر گرفته نشود، در چنين حالتي مي‌توان از دستور اسمبلر ASSUME به صورت زير استفاده نمود:

Segment_register: NOTHING

يک اسمبلر به طور معمول شمارنده موقعيت را از ابتداي هر سگمنت از صفر شورع کرده و آن را به تعداد بايت‌هاي لازم براي هر دستورالعمل افزايش مي‌دهد. مي‌توان از اسمبلر خواست که براي مقدار ابتدايي شمارنده موقعيت، مقدار خاصي را درنظر بگيرد. MASM و بسياري از اسمبلرهاي ديگر براي اين منظور از دستور اسمبلر Org استفاده مي‌نمايند. شکل کلي اين دستور اسمبلر به صورت زير است:

ORG value

که در آن value يک آفست را مشخص مي‌کند. وقتي MASM به دستور اسمبلر ORG برخورد مي‌نمايد، شمارنده موقعيت را با مقدار مشخص شده پرمي‌نمايد.

 

MASM دستورات اسمبلر EVEN و ALIGN را عرضه مي‌کند، اين دستورات اسمبلر بر روي شمارنده موقعيت اثر مي‌گذارند.

معمولاً دستور اسمبلر EVEN همراه با دستور اسمبلر DW به کار مي‌رود تا يک کلمه را تعريف نمايد. اگر شمارنده موقعيت زودج باشد دستور اسمبلر EVEN هيچ اثري نخواهد داشت ولي اگر شمارنده موقعيت فرد باشد، MASM يک دستورالعمل nop (بايت تکي برابر 90) را درج مي‌کند تا شمارنده موقعيت در زمان اسمبل شدن DW زوج باشد.

 

هر فايل منبع مي‌تواند داراي يک دستور اسمبلر TITLE باشد. اين دستور داراي ساختار زير است:

TITLE  text

که در آن text هر رشته‌اي از کاراکترها تا حداکثر 60 کاراکتر است. رشته‌اي که به وسيله اين دستور اسمبلر مشخص مي‌شود در دومين خط هر صفحه از فايل ليست اسمبلي نوشته مي‌شود.


ماكروها و اسمبلي شرطي

تعريف و بسط دادن ماکروها

 

اسمبلر يک ماکرو را به دستورالعمل‌هاي تشکيل دهنده ماکروي مزبور بسط داده و سپس اين دستورالعمل‌هاي جديد را اسمبل مي‌کند.

تعريف يک ماکرو شبيه تعريف يک روال در يک زبان سطح بالا مي‌باشد.

خط اول، نام ماکروي موردنظر و ليست پارامترها را ذکر مي‌کند؛ قسمت اصلي تعريف يک ماکرو متشکل از دستورالعمل‌هايي است که طرز عمل ماکروي مربوط را برحسب پارامترهاي آن بيان مي‌کند.

يک ماکرو همچنين مانند يک روال زبان‌هاي سطح بالا فراخواني مي‌شود. نام ماکروي موردنظر و به دنبال آن ليست آرگومان‌ها ذکر مي‌گردد.

 

تفاوت روال و ماکرو:

فراخواني يک روال در يک زبان سطح بالا به تعدادي دستورالعمل‌هاي مربوط به انتقال دادن آرگومان‌هاي ذکر شده در دستورالعمل call، کامپايل مي‌شود.

فراخواني يک ماکرو عملاً به دستورالعملهاي داده شده در تعريف ماکروي مزبور بسط داده شده و آرگومان‌ها جايگزين پارامترهاي استفاده شده در تعريف ماکروي مربوط مي‌گردد.

کد يک ماکرو با هر بار فراخواني آن تکرار مي‌شود، اما تنها يک نسخه از کد يک روال وجود دارد.

با توجه به اينکه هيچگونه بالا سري براي انتقال دادن پارامترها يا براي دستورالعمل‌هاي call و ret وجود ندارد، معمولاً ماکروها سريعتر از فراخواني روال‌ها اجرا مي‌شوند ولي اين معمولاً به بهاي طولاني تر شدن کد هدف در مورد فراخواني ماکروها، صورت مي‌گيرد.

 

تعريف يک ماکرو در بين دستورات MACRO و ENDM قرار داده مي‌شود.

شکل تعريف يک ماکرو به صورت زير مي‌باشد.

ليست پارامترها MACRO نام

 دستورالعملهاي زبان اسمبلي

  ENDM

تعريف يک ماکرو مي‌تواند در هر جاي برنامه اسمبلي ذکر شود به شرط اينکه اين تعريف قبل از فراخواني‌هاي آن بيايد.

 

اسمبلي شرطي

مواردي که مورد استفاده مي‌تواند قرار بگيرد:

 مواقعي که برنامه‌نويس مي‌خواهد که اشکال نسبتاً متفاوتي از يک برنامه يا يک روال را توليد نمايد.

 زماني که برنامه‌نويس بخواهد در سطح زبان ماشين عمليات ورودي يا خروجي را انجام دهد که تنها آدرس درگاه‌هاي مورد استفاده در ماشين‌هاي مختلف تغيير کند.

زماني که بسط يک ماکرو برحسب تعداد و نوع آرگومان‌ها تغيير پيدا مي‌کند.

 

دستور %OUT به MASM مي‌گويد که يک پيغامي را روي دستگاه خروجي استاندارد که معمولاً صفحه نمايش مي‌باشد، چاپ نمايد:

%OUT message

که message مي‌تواند مجموعه‌اي از کاراکترها از جمله کاراکتر خالي و علائم املايي باشد. استفاده از دستور %out‌منحصر به ماکروها يا اسمبلي شرطي نيست.

ماکروها فايل IO.H

ماکروهاي فايل IO.H براي ارائه دستيابي صحيح و آسان به دستگاه‌هاي ورودي و خروجي استاندارد، طراحي شده‌اند.

دستور XLIST باعث جلوگيري از ليست شدن تمام کد منبع به ويژه محتواي فايل IO.H مي‌گردد.

دستور EXTRN روال‌هاي خارجي فراخواني شده توسط ماکروها را معرفي مي‌کند.


پایان