انواع روش های آدرس دهی در میکرو کنترل

مبحث مهمی که در برنامه نویسی به زبان اسمبلی وجود دارد شیوه های آدرس دهی است .منظور از آدرس دهی روش دستیابی میکرو پروسسور به اطلاعات است آدرس دهی ، مبدا و مقصد داده را تعیین می کند و اینکه در جریان انتقال داده از مقصد به مبدا چه عملیاتی بایستی انجام شود .قبل از پرداختن به تشریح دستور العمل های اسمبلی 8051 ، انواع شیوه های آدرس دهی را بیان می کنیم.
در 8051 هشت نوع آدرس دهی وجود دارد که در این مطلب این شیوه های آدرس دهی را با هم بررسی خواهیم کرد.

• آدرس دهی ثبات(Register Addressing)
• آدرس دهی مستقیم (Direct Addressing)
• آدرس دهی غیر مستقیم (Indirect Addressing)
• آدرس دهی فوری (Immediate Addressing)
• آدرس دهی نسبی (Relative Addressing)
• آدرس دهی مطلق( Absolute Addressing)
• آدرس دهی طولانی (Long addressing)
• آدرس دهی دهی اندیس دار (Index Addressing)
آدرس دهی ثبات:

همانگونه که می دانید در 8051 هشت ثبات با نام بانک ثبات وجود دارند که این ثبات ها به صورت تک تک با نام های R0-R7 شناخته می شوند تعدادی از دستور العمل های 8051 بر روی این ثبات ها کار می کنند این دستور العمل ها را دستور های با آدرس دهی ثبات گویند.البته چند دستور دیگر هم وجود دارند که فقط بر روی یک ثبات خاص عمل میکنند مانند ثبات های A,B و ثبات DPTR(همان اشاره گر داده) و بیت C (داده نقلی) ثبات PSW( کلمه وضعیت برنامه) این دستور العمل ها هم آدرس دهی ثبات را به کار گرفته اند.

مثالی از این نوع دستورات به صورت زیر است (اگر مفهوم دستورات را متوجه نمی شوید اشکالی ندارد در مقاله های بعدی توضیح کافی بر روی تک تک دستورات داده خواهد شد ):

ADD A,R0
INC DPTR
MUL AB
DIV AB



آدرس دهی مستقیم :

گفتیم که هر بایت (8 بیت) از حافظه میکرو به وسیله عددی منحصر به فرد که شماره ردیف آن بایت است مشخص می شود این عدد منحصر به فرد آدرس نام دارد . از این جهت می گوییم منحصر به فرد زیرا هیچ دو بایت از حافظه ی میکرو دارای یک آدرس نیستند!.
با استفاده از این آدرس می توان به کلیه مکانهای حافظه دسترسی داشت .آدرس دهی مستقیم از این آدرس استفاده می کند .
علاوه بر آدرس ، بیشتر مکان های حافظه دارای نام نیز هستند.برای مثال پورت یک، هم دارای آدرس 90H است و هم نام P1 را دارد . استفاده از هردو (نام یا آدرس) در برنامه نویسی مجاز است .
در برنامه نویسی هنگامی که عددی را بدون هیچ پیشوندی می نویسند نشان دهنده استفاده از آدرس دهی مستقیم است.

آدرس دهی غیر مستقیم :

آدرس دهی غیر مستقیم نیز از آدرس بیات مورد نظر استفاده می کند .تفاوت آن با آدرس دهی مستقیم این است که در آدرس دهی غیر مستقیم آدرس مکان حافظه ابتدا در یکی از ثبات های بانک ثبات قرار می گیرد وسپس ثبات مذکور به همراه پیشوند @( At sign) در دستور العمل استفاده می شود.

کاربرد این نوع آدرس دهی برای مواقعی است که آدرس یک متغیر بایستی در زمان اجرای برنامه ، نه در زمان نوشتن کد ، محاسبه شود و نیز هنگام استفاده از مکانهای متوالی حافظه نیز باید از آدرس دهی غیر مستقیم استفاده کنیم . در موارد بالا نمی توانیم از آدرس دهی مستقیم و ثبات استفاده کنیم زیرا این دو آدرس دهی در هنگام کامپایل برنامه به آدرس مکان حافظه نیاز دارند در حالی که ما آدرس مکان حافظه را نمی دانیم .
برای فهم بیشتر مطلب دو دستور زبر را در نظر بگیرید:

MOV R0,#90h
MOV @R0,A



دستور اول عدد 90 در مبنای شانزده زا در ثبات R0 قرار می دهد – به علامت #( number sign) قبل از عدد توجه کنید مبحث بعدی آدرس دهی ماست- عدد 90h آدرس پورت یک می باشد . دستور دوم به میکرو دستور می دهد تا محتوای ثبات A را در آدرسی که در R0 است( یا مکانی که R0 به آن اشاره می کند ) قرار بده .
جمله بالا در مفاهیم برنامه نویسی به نام اشاره گر معروف است . اشاره گر متغیری است که آدرس مکانی از حافظه را در خود نگه می دارد .
در این دستور @R0 معادل همان P1 است .
آدرس دهی فوری یا بلافصل :

در صورتی که بخواهیم یک عدد ثابت – نه یک آدرس – را در مکانی از حافظه قرار دهیم از آدرس دهی فوری استفاده می کنیم .دستور اول در مثال قبلی نوعی از آدرس دهی فوری بود . مشخصه ی آدرس دهی فوری استفاده از پیشوند # قبل از عدد است .
در صورتی که در یک دستور از عددی استفاده کنیم اگر عدد بدون پیشوند باشد نوع آدرس دهی مستقیم است و در صورتی که عدد پیشوند # داشته باشد آدرس دهی فوری خواهد بود .به این دو دستور توجه کنید تا این جمله را بهتر متوجه شوید:

MOV A,#90h
MOV A,90h



دستور اول عدد 90 در مبنای شانزده را در ثبات A قرار می دهد . بعد از اجرای دستور مطمئن هستیم که محتوای ثبات A ، 90h است . دستور دوم مقداری را که در آدرس 90h حافظه است در ثبات A قرار می دهد یادآوری می کنم که 90h آدرس پورت یک است .بنابراین هر عددی که بر روی پورت یک قرار داشته باشد در درون ثبات A قرار خواهد گرفت .و ما از مقدار این عدد هیچ اطلاعی نداریم .
توجه:
در برنامه نویسی میکرو می توان از مبنا های عددی مختلف ستفاده کرد . این کار با اسفاده از نوشتن عدد و نوشتن مشخصهی عدد درست بعد از آن ، به عنوان پسوند (در سمت راست عدد) صورت می گیرد .
مشخصه ی مبنا های عددی به صورت زیر است:
B برای مبنای دودویی یا binary
D برای مبنای دهدهی یاdecimal
H برای مبنای شانزدهی یا hexadecimal

در صورتی که قصد استفاده از مبنای ده را داشته باشیم می توانیم از پسوند D صرفنظر کنیم مبنای ده پیش فرض کامپایلر است .
اگر از مبنای شانزدهی در برنامه استفاده کردیم اگر اولین رقم سمت چپ عدد ( پر ارزش ترین رقم ) رقمی بین A-F در مبنای شانزده بود باید قبل از عدد یک صفر 0 قرار دهیم مثلا عدد #FFh را باید به صورت #0FFh بنویسیم.



آدرس دهی نسبی :

این نوع آدرس دهی در چند دستورالعمل پرشی به کار رفته است.(مانند sjmp) با استفاده از این نوع آدرس دهی می توان به 127 بایت بالاتر و 127 بایت پاینتر از مکان فعلی برنامه پرش کرد . هنگامی که کامپایر به این نوع دستورات پرشی می رسد آدرس مبدا را از آدرس مقصد تفریق می کند ونتیجه را به شمارنده برنامه اضافه می کند (pc) دستور زیر را در نظر بگیرید:

90 sjmp 100


اکنون در مکان 90 حافظه هستیم برنامه می خواهد به مکان 100 پرش کوتاه انجام دهد .آدرس مبدا از مقصد کم می شود (100-90) و به pc ، +10 واحد اضافه می گردد.

مزیت این نوع آدرس دهی این است که کد مستقل از مکان ایجاد می کند.

آدرس دهی مطلق :
تنها دو دستور العمل Acall,Ajmp از این نوع آدرس دهی استفاده می کنند آدرس مبدا و مقصد هر دو باید در یک صفحه دو کیلو بایتی از حافظه باشند . این دستورات کد وابسته به مکان تولید می کنند .
آدرس دهی طولانی :

دو دستور Ljmp ,Lcall از این نوع آدرس دهی استفاده می کنند.مبدا و مقصد می توانند در یک صفحه 64 کیلو بایتی باشند ( کل فضای حافظه پوشش داده شده است ).
این نوع آدرس دهی هم وابسته به مکان است.
توجه :
منظور از کد وابسته به مکان بدین صورت است:
فرض کنید برنامه ای نوشته ایم که از فضای 100 حافظه شروع می شود .برنامه زیر


100 sjmp there
101….
….
….
105 there :Ajmp 110
…..
….
110 here: ------



در این برنامه از آدرس 100 به 105 که دارای برچسب there است پرش می کند و از there هم به here پرش میکند .حال اگر همین برنامه را روی میکروی دیگری که برنامه از آدرس 50 شروع شده باشد اجرا کنیم منطق برنامه به صورت زیر در می آید:
50 sjmp there
101….
….
….
55 there :Ajmp 110
…..
….
60 here: ------
--- ----- ----
110 :---- ----



دستور sjmp که از آدرس دهی نسبی استفاده می کند به مکان درست there پرش می کند اما دستور ajmp که از آدرس دهی مطلق استفاده می کند به جای پرش به here به مکان 10 حافظه پرش می کند که اصلا مورد نظر برنامه نویس نبوده است !!!
برای رفع این مشکل از دستور ORG در ابتدای برنامه استفاده می کنیم تا به کامپایلر بگوییم که برنامه ما باید از چه مکان حافظه ای بایستی شروع شود .

ORG 100
100 sjmp there
101….
….
….
105 there :Ajmp 110
…..
….
110 here: ------



آدرس دهی اندیس دار:

این آدرس دهی از یک ثبات پایه (pc یا DPTR ) و یک فاصله نسبی (A) برای دستور العمل های JMPو MOVC استفاده می کند این نوع آدرس دهی در نوشتن جداول جستجو(LOOKUP Table) استفاده می شوددر آینده نمونه ای از این نوع برنامه ها را خواهیم نوشت .