در کار با ریزپردازنده که معمولاً با زبان اسمبلی انجام میشود، سه روش مختلف برای آدرس دهی برنامه (با استفاده از دستورات JMP یا پرش و CALL یا فراخوانی) وجود دارد: مستقیم، نسبی و غیرمستقیم.
در این مطلب شیوه عملکرد این سه روش آدرس دهی حافظه را بررسی میکنیم. روش ها و منطق کار در اکثر ریزپردازنده ها مشابه هم هستند ولی در مثال های گفته شده، پایه بحث را ریزپردازنده های اینتل در نظر گرفته ایم.
آدرس دهی مستقیم حافظه برنامه
آدرس دهی مستقیم حافظه برنامه روشی است که در بسیاری از ریزپردازنده های اولیه برای دستورات JMP و CALL به کار میرفت. از آدرس دهی مستقیم حافظه برنامه نیز در زبان های سطح بالا، استفاده میشود مانند دستورات GO TO و GO SUB در زبان BASIC.
ریزپردازنده ها از این روش آدرس دهی در اجرای برنامه ها استفاده میکند، البته نه به اندازه روش های نسبی و غیر مستقیم.
دستورات برای آدرس دهی مستقیم حافظه برنامه، آدرس را با کد عمل ذخیره میکنند. به عنوان مثال اگر یک برنامه بخواهد به مکان 10000H حافظه برای دستور بعدی پرش کند، آدرس 10000H پس از کد عمل در حافظه ذخیره خواهد.
در دستور زیر، CS را با 1000H و IP را با 0000H بارگزاری کرده تا به مکان 10000H حافظه برای دستور پرش نماید.
// OP Code Offset(down) Offset(up) Block(down) Block(up) // E A 0 0 0 0 0 0 1 0 JMP [10000H]
یک پرش درون قطعه ای، پرشی به هر مکان حافظه درون سیستم کلی حافظه است.
پرش مستیم اغلب پرش دور نامیده میشود زیرا میتواند به هر مکان حافظه دستور بعدی پرش نماید. در حالت واقعی، یک پرش دور به هر مکان درون اولین 1M بایت حافظه با تغییر هر دو ثبات CS و IP دسترسی می یابد.
در حالت حفاظت شده، پرشی دور به توصیف گر قطعه کد از جدول توصیف گر، دستیابی پیدا میکند و به آن اجازه میدهد تا به هر مکان در محدوده آدرس 4 گیگابایت در ریزپردازنده های 80386 تا پنتیوم 4 پرش نماید.
تنها دستور دیگری که از آدرس دهی مستقیم برنامه استفاده میکند، دستور درون قطعه ای CALL است. معمولاٌ نام یک آدرس حافظه، یک برچسب نامیده میشود که به جای آدرس حقیقی عددی، مکان فراخوانده یا پرش شده می باشد.
هنگام استفاده از یک برچسب با دستور CALL یا JMP، بیشتر اسمبلرها بهترین روش آدرس دهی برنامه را انتخاب خواهند کرد.
آدرس دهی نسبی حافظه برنامه
آدرس دهی نسبی حافظه برنامه در همه ریزپردازنده های قدیمی موجود نیست اما در این خانواده از ریزپردازنده های اینتل وجود دارد.
واژه نسبی به معنی نسبت به اشاره گر دستور (IP) است. به عنوان مثال، اگر یک دستور JMP به دو بایت بعدی حافظه حرکت نماید، آدرس آن نسبت به اشاره گر دستور، 2 است که به اشاره گر دستور اضافه میگردد.
این شیوه آدرس دستور بعدی برنامه را توسعه میدهد. توجه کنید که دستور JMP یک دستور یک بایتی است؛ با جابجایی یک یا دو بایتی که به اشاره گر دستور اضافه میشود، یک جابجایی یک بایتی در پرش های کوتاه (short) و جابجایی با پرش های نزدیک (near) و فراخوانی ها، صورت میگیرد.
هر دو نوع آنها به عنوان پرش های درون قطعه ای در نظر گرفته خواهند شد. (یک پرش درون قطعه ای پرش به مکانی درون قطعه کد جاری است.)
در ریزپردازنده 80386 و بالاتر از آن، این جابجایی نیز میتواند یک مقدار 32 بیتی باشد که این امکان را میدهد تا آدرس دهی نسبی برای مکان درون قطعه های کد 4 گیگابایتی به کار برده شود.
دستورات JMP و CALL نسبی شامل جابجایی علامت دار 8 یا 16 بیتی می باشند که اجازه میدهد تا یک ارجاع مستقیم یا معکوس به حافظه صورت گیرد. (ریزپردازنده 80386 و بالاتر از آن میتواند جابجایی 8 بیتی یا 32 بیتی داشته باشد)
همه اسمبلرها به طور خودکار این فاصله برای جابجایی را محاسبه نموده و شکل مناسب یک، دو یا چهار بایتی را انتخاب میکنند.
اگر این فاصله برای جابجایی دو بایتی در ریزپردازنده 8086 تا 80286 بیش از اندازه دور باشد، بعضی اسمبلرها از پرش مستقیم استفاده می نمایند.
یک جابجایی 8 بیتی (کوتاه) یک محدوده پرش میان 127+ و 128- بایت را از دستور بعدی دارد؛ یک جابجایی 16 بیتی (نزدیک) محدوده 32+ و 32+ کیلوبایت را داراست.
در 80386 و بالاتر از آن، جابجایی 32 بیتی یک محدوده 2 گیگابایتی را مجاز میداند. در نظر داشته باشید که جابجایی 32 بیتی فقط میتواند در مد حفاظت شده به کار رود.
آدرس دهی غیرمستقیم حافظه برنامه
ریزپردازنده امکان چند شیوه آدرس دهی غیرمستقیم حافظه را برای دستورات JMP و CALL فراهم می آورد. تعداد دستورات قابل قبول پرش غیرمستقیم در برنامه نسبت به سایر دستورات کمی بیشتر است.
این دستورات میتوانند از هر ثبات 16 بیتی (AX ، BX ، CX ، DX ، SP ، BP ، DI یا SI) ، ثبات نسبی ([BP] ، [BX] یا [SI]) و هر ثبات نسبی با یک جابجایی استفاده نمایند.
ریزپردازنده 80386 و بالاتر از آن نیز میتوانند ثبات توسعه یافته را برای نگهداری آدرس یا آدرس غیرمستقیم یک JMP یا CALL نسبی به کار برند.
به عنوان مثال دستور JMP EAX به مکان افزوده شده به وسیله ثبات EAX پرش خواهد کرد.
اگر یک ثبات 16 بیتی آدرس یک دستور JMP را نگه دارد، پرش نزدیک است. به عنوان مثال ثبات BX حاوی 1000H است و یک دستور JMP BX اجرا میشود، ریزپردازنده به آدرس افست 1000H در قطعه کد جاری پرش میکند.
اگر یک ثبات نسبی آدرسی را نگه داری کند، پرش به عنوان پرش نزدیک در نظر گرفته خواهد شد. به عنوان مثال دستور JMP [BX] به مکان حافظه ای درون قطعه داده در آدرس افست موجود در BX مراجعه میکند.
این آدرس افست یک عدد 16 بیتی است که به عنوان آدرس افست در پرش درون قطعه ای به کار میرود. این پرش گاهی پرش غیرمستقیم – غیرمستقیم یا پرش جفت غیرمستقیم نامیده میشود.
این آموزش بیش از ۳ سال قبل ارسال شده و اکنون در لیست بهروزرسانیهای سایت قرار دارد. اگر پیشنهاد یا انتقادی برای بهبود آموزش دارید، خوشحال میشیم به ما اطلاع بدهید.
سلام وقتتون بخیر
اگه توی یه کامپیوتر ،حافظه 8192×18 داشته باشیم و فقط یک روش آدرس دهی وجود داشته باشه، چند نوع دستور میشه تعریف کرد؟؟؟
تشکر ^_^
بسيار دقيق بود
خوشحالم براتون مفید بوده علیرضای عزیز.
جناب خوب هستید امکانش هست بگید جواب این چیه یا توضیح بدی با جواب
سوال این بوده
فرض کنید در cs 12E0H در IP عدد 2000AH را داریم آدرس خط برنامه چیست
سلام
واقعیتش خیلی وقته از حل چنین مسائلی دور بودم، مطمئن نیستم چطور باید حل بشه! 😉
مشابه مثال JMP همین آموزش احتمالاً بتونید پیش برید. و اینکه حواستون باشه غیر از H آخر، بقیه یک مقدار هگز هستند.