دوشنبه , ۳ تیر ۱۳۹۸
آخرین مطالب
LINK TABLES
خانه | میکروکنترلر | دوره آموزشی AVR | برنامه نویسی اسمبلی برای AVR (جلسه ۸)

برنامه نویسی اسمبلی برای AVR (جلسه ۸)

آدرس دهی در AVR

داده ها می توانند درون یک ثبات، بر روی حافظه، یا به صورت مقدار بی واسطه باشند.CPU با روش های مختلفی به داده ها دسترسی دارد که به این روشها مدهای آدرس دهی گویند.

AVRجمعا ۱۳ مد آدرس دهی مجزا دارد که می توان آنها را به ۶ دسته تقسیم کرد:

  • تک ثباتی(بی واسطه)
  • ثبات
  • مستقیم
  • غیر مستقیم ثبات
  • مستقیم فلاش
  • غیر مستقیم فلاش

مد آدرس دهی تک ثباتی

 در این مد عملوند یک ثبات است.

مثال:

در دستور آخر یک مقدار ثابت با یک ثبات وجود دارد در برخی میکروکنترلر ها به این مد آدرس دهی آدرس دهی بی واسطه می گویند ولی در AVR به عنوان زیر مجموعه ای از مد آدرس دهی تک ثباتی در نظر گرفته شده است.

مد آدرس دهی دو ثباتی

 در این مد از دو ثبات برای نگهداری داده استفاده می شود.

مثال:

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

در این مد محتوای عملوند در یک خانه حافظه رم با آدرس مشخص قرار دارد، و این آدرس به عنوان بخشی از دستور داده شده است.

مثال:

مد آدرس دهی مستقیم I/O

در این مد آدرس دهی فقط ثبات های استاندارد I/O پشتیبانی می شوند.

دستورات  IN و OUT از این مد آدرس دهی استفاده می کنند.

مثال:

مد آدرس دهی غیر مستقیم ثبات

در این مد آدرس دهی از یک ثبات به عنوان اشاره گر به خانه داده استفاده می شود.در AVR برای این منظور از سه ثبات ۱۶ بیتی  به نام های X,Y,Z  برای این منظور استفاده می شود.هر یک از این ثبات ها از ترکیب دو ثبات همه منظوره مشخص تشکیل شده است.برای دسترسی به بایت های بالا و پایین این ثبات ها می توان از نام های ZH,ZL,YH,YL,XH,XL استفاده کرد.که به ترتیب نام دیگر ثبات های   R31,R30,R29,R28,R27,R26 می باشند.

برای مثال دستور LDI  XL,0x30″” با دستور “LDI  R26,0x30” یکسان است زیرا XL نام دیگر R26 می باشد.

برای استفاده از این ثبات ها به عنوان اشاره گر از دستور “LD” و “ST” استفاده می کنیم.

مثال:

با اجرای دستور آخر در مثال بالا محتویات ثبات R18 در خانه حافظه با آدرس ۰x130 کپی میشود.
با اجرای دستور آخر در مثال بالا محتویات خانه حافظه با آدرس  ۰x130در ثبات R18 در کپی میشود.

از مزایای مد آدرس دهی غیرمستقیم ثبات دسترسی پویا به داده می باشد.

ما می توانیم با استفاده ازدستور INC و DEC مقدار اشاره گر را به صورت دستی افزایش و یا کاهش دهیم.

مثال:

با این حال در این روش باید دقت کنیم که در هنگام به آخر رسیدن شمارش ثبات پایین ، ثبات بالا یک واحد افزایش و یا کاهش  پیدا کند زیرا دستور  INCو DEC رقم نقلی را به ثبات بالا انتقال نمیدهد.AVR  گزینه های افزایش و کاهش اتوماتیک را برای مقابله با این مشکل به ما می دهد.

جدول زیر ساختار دستور LD را در چنیین حالت هایی به ما می دهد.با استفاده از این دستور می توان محتویات آدرسی را که اشاره گر به آن اشاره می کند در درون ثبات همه منظوره کپی کرد.

دستور توضیحات
LD  RN,X پس از کپی خانه ای که X به آن اشاره می کند به درون ثبات RN، X بدون تغییر می ماند.
+LD  RN,X پس از کپی خانه ای که X به آن اشاره می کند به درون ثبات RN،به X یکی اضافه می شود.
LD  RN,-X از X یکی کم می شود، سپس محتویات خانه ای که X به آن اشاره میکند به درون ثبات RN کپی می شود.
LD  RN,Y پس از کپی خانه ای که Y به آن اشاره می کند به درون ثبات RN، Y بدون تغییر می ماند.
+LD  RN, Y پس از کپی خانه ای که Y به آن اشاره می کند به درون ثبات RN،به Y یکی اضافه می شود.
LD  RN,-Y از Y یکی کم می شود، سپس محتویات خانه ای که Y به آن اشاره میکند به درون ثبات RN کپی می شود.
LDD  RN,Y+q پس از کپی خانه ای که Y+q به آن اشاره می کند به درون ثبات RN، Y بدون تغییر می ماند.
LD  RN,Z پس از کپی خانه ای که Z به آن اشاره می کند به درون ثبات RN، Z بدون تغییر می ماند.
+LD  RN,Z پس از کپی خانه ای که Z به آن اشاره می کند به درون ثبات RN،به Z یکی اضافه می شود.
LD  RN,-Z از Y یکی کم می شود، سپس محتویات خانه ای که Z به آن اشاره میکند به درون ثبات RN کپی می شود.
LDD  RN,Z+q پس از کپی خانه ای که Z+q به آن اشاره می کند به درون ثبات RN، Z بدون تغییر می ماند.

در مقابل دستور LD دستور ST وجود دارد که با استفاده از آن می توان محتویات یک ثبات همه منظوره را در خانه ای آدرس آن در درون اشاره گر وجود دارد ذخیره کرد.

جدول زیر حالت های مختلف دستور ST را نشان می دهد.

دستور

توضیحات

ST  X,RN پس از کپی ثبات  RN به درون خانه ای که X به آن اشاره می کند ، X بدون تغییر می ماند.
ST  X+,RN پس از کپی ثبات RN به درون خانه ای که X به آن اشاره می کند ،به X یکی اضافه می شود.
ST  -X,RN از X یکی کم می شود، سپس محتویات ثبات RN به درون خانه ای که X به آن اشاره میکند کپی می شود.
ST  Y,RN پس از کپی ثبات  RN به درون خانه ای که Y به آن اشاره می کند ، Y بدون تغییر می ماند.
ST  Y+,RN پس از کپی ثبات RN به درون خانه ای که Y به آن اشاره می کند ،به Y یکی اضافه می شود.
ST  -Y,RN از Y یکی کم می شود، سپس محتویات ثبات RN به درون خانه ای که Y به آن اشاره میکند کپی می شود.
STD  Y+q,RN پس از کپی ثبات RN به درون خانه ای که Y+q به آن اشاره می کند ، Y بدون تغییر می ماند.
ST  Z,RN پس از کپی ثبات  RN به درون خانه ای که Z به آن اشاره می کند ، Z بدون تغییر می ماند.
ST  Z+,RN پس از کپی ثبات RN به درون خانه ای که Z به آن اشاره می کند ،به Z یکی اضافه می شود.
ST  -Z,RN از Y یکی کم می شود، سپس محتویات ثبات RN به درون خانه ای که Z به آن اشاره میکند کپی می شود.
STD  Z+q,RN پس از کپی ثبات RN به درون خانه ای که Y+q به آن اشاره می کند ، Z بدون تغییر می ماند.

لازم به ذکر است که در جدول بالا دستور LDD از روش غیر مستقیم ثبات با جابجایی استفاده می کند.

جدول جستجو و پردازش جدول

در AVR از فضای کد می توانیم برای ذخیره داده های ثابت استفاده کنیم. نحوه دسترسی به این ثبات ها در این بخش توضیح داده شده است.

برای ذخیره داده های ثابت در فضای رام از دستورالعمل (DB(Define Byte. استفاده می کنیم. اگر با استفاده از این دستورالعمل چند بایت داده را اختصاص دهیم بایت اول در بایت پایین خانه رام و بایت دوم در بایت بالای آن قرار می گیرد.

برای مقادیر بزرگتر از ۰xFF ولی کوچکتر از ۰xFFFF از شبه دستور DWin. استفاده می کنیم.

مثال:

برای نمونه ۰x34، در بایت پایین خانه ۰x600 قرار گرفته و ۰x12 به بایت بالای خانه ۰x600 می رود.

برای خواندن داده ها از روی رام به یک اشاره گر نیاز داریم.برای این منظور می توانیم از ثبات Z استفاده کنیم.به این روش مد آدرس دهی فلش می گویند.دو روش در ان مد آدرس دهی وجود دارد، مد آدرس دهی ثابت آدرس دهی برنامه و مد آدرس دهی حافظه برنامه با افزایش بعدی.در روش اول محتوای اشاره گر Z بعد از اجرای دستور تغییری نمی کند در حالی که در روش دوم بعد از هر بار اجرای دستور یک واحد به محتوای Z اضافه می شود.

دستورات خواندن جدول در AVR

دستور

توضیحات

LPM  RN,Z محتویات خانه ای از رام را که توسط Z به آن اشاره می شود، در ثبات RN ذخیره می کند و بعد از اجرای دستور Z هیچ تغییری نمی کند.
+LPM  RN,Z محتویات خانه ای از رام را که توسط Z به آن اشاره می شود، در ثبات RN ذخیره می کند و بعد از اجرای دستور یک واحد به Z اضافه می شود هیچ تغییری نمی کند.

همانطور که در مثال بالا دیدید از برچسب هایی قبل از شبه دستور DW. آورده شده که می توان به وسیله آنها از مکان مشخصی داده برداری کرد. برای این کار از دوتابع() HIGH و ()LOW استفاده می کنیم.این دو تابع مقدارهای بالا و پایین یک مقدار ۱۶ بیتی را به ما میدهد. برچسبهای مذکور آدرسهای ۱۶ بیتی هستند که می توان با این دو تابع مقدار آنها را در اشاره گر Z بار کرد.در واقع برچسبها همانطور که از نامشان پیداست صورت دیگر اعدادند، که این اعداد میتوانند یک آدرس و یا یک داده ثابت باشند.بعدا در این مورد توضیح بیشتری میدهیم.

مثال:

یا

یا

در مثال بالا هر سه قطعه کد یک عمل را انجام می دهند.

در AVR امکان نوشتن داده در حافظه رام وجود دارد که این کار به وسیله دستور SPM انجام می شود.

آدرس پذیری بیتی

برخی از میکروپروسسورها از قبیل پنتیوم به برنامه اجازه می دهند که تنها به صورت بایت به بایت به ثباتها و پورت های I/O دسترسی داشته باشند.اما در AVR این امکان وجود دارد که به صورت بیتی بتوانیم به ثبات ها و پورت ها دسترسی داشته باشیم.یعنی اینکه بتوانیم یک بیت دلخواه از یک ثبات را بدون آنکه بیت های دیگر ثبات تاثیر ببینند تغییر دهیم.

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

دست کاری بیت های همه منظوره:

دستور

توضیحات

SBR  RN,K این دستور یک بیت مشخص در ثبات همه منظوره را یک می کند.K یک مقدار ۸ بیتی است.این دستور باعث یک شدن هر یک از بیت های ثبات همه منظوره که متغیر k در آن یک است می شود.
CBR  RN,K این دستور یک بیت مشخص در ثبات همه منظوره را صفر می کند.K یک مقدار ۸ بیتی است.این دستور باعث یک شدن هر یک از بیت های ثبات همه منظوره که متغیر k در آن صفر است می شود.
SBI  P,b این دستور یک بیت مشخص در ثبات I/O را یک می کند.b شماره بیت مورد نظر در ثبات I/O می باشد.p ثبات I/O است.
CBI  P,b این دستور یک بیت مشخص در ثبات I/O را صفر می کند.b شماره بیت مورد نظر در ثبات I/O می باشد.p ثبات I/O است.

مثال:

آدرس پذیری بیتی ثبات همه منظوره:

دستور

توضیحات

BRBS  S,K پرش به شرط یک بودن پرچم وضعیت(S نمایانگر شماره بیت در ثبات وضعیت است و K آدرس نسبی خانه هدف پرش است)
BRBC  S,K پرش به شرط یک بودن پرچم وضعیت(S نمایانگر شماره بیت در ثبات وضعیت است و K آدرس نسبی خانه هدف پرش است)
BSET  S این دستور بیت دلخواه را در ثبات همه منظوره یک می کند.(S نمایانگر شماره بیت در ثبات وضعیت است)
BCLR  S این دستور بیت دلخواه را در ثبات همه منظوره صفر می کند.(S نمایانگر شماره بیت در ثبات وضعیت است)
BRCS اگر C=1 پرش کن.
BRCC اگر C=0 پرش کن.
BRLO اگر C=1 پرش کن.
BRSH اگر C=0 پرش کن.
BREQ اگر Z=1 پرش کن.
BRNE اگر Z=0 پرش کن.
BRMI اگر N=1 پرش کن.
BRPL اگر N=0 پرش کن.
BRVS اگر V=1 پرش کن.
BRVC اگر V=0 پرش کن.
BRLT اگر S=1 پرش کن.
BRGE اگر S=0 پرش کن.
BRHS اگر H=1 پرش کن.
BRHC اگر H=0 پرش کن.
BRTS اگر T=1 پرش کن.
BRTC اگر T=0 پرش کن.
BRIE اگر I=1 پرش کن.
BRID اگر I=0 پرش کن.
SEC C=1
SEZ Z=1
SEN N=1
SEV V=1
SES S=1
SEH H=1
SET T=1
SEI I=1
CLC C=0
CLZ Z=0
CLN N=0
CLV V=0
CLS S=0
CLH H=0
CLT T=0
CLI I=0

کپی کردن یک بیت:در جلسات قبلی دیدید که یکی از بیت های ثبات وضعیت بیت (T(Temporary یا بیت موقت بود.این بیت برای کپی کردن یک بیت داده از یک ثبات همه منظوره به یک ثبات همه منظوره دیگر به کار می رود.

دستورات (BST(bit stor from register to T و (BLD(bit load from T to registe می توانند برای این منظور استفاده شوند.

دستور

توضیحات

BST  RN,b بیت  bرا از RN بر روی پرچم T ذخیره می کند.
BLD  RN,b پرچم T راربر روی بیت  b از RN ذخیره می کند.

مثال:

چک کردن بیت ها

در AVR دستوراتی وجود دارد که بوسیله آنها می توان بیت های یک ثبات همه منظوره و یا I/O را از لحاظ صفر یا یک بودن بررسی کرد.به جدول زیر دقت کنید.

دستور

توضیحات

SBRC  RN,b این دستور یک بیت از یک ثبات همه منظوره را بررسی کرده، درصورت صفر بودن آن بیت، دستوری را که درست زیر آن قرار دارد نادیده میگیرد.
SBRS  RN,b این دستور یک بیت از یک ثبات همه منظوره را بررسی کرده، درصورت یک بودن آن بیت، دستوری را که درست زیر آن قرار دارد نادیده میگیرد.
SBIC  P,b این دستور یک بیت از یک ثبات I/O را بررسی کرده، درصورت صفر بودن آن بیت، دستوری را که درست زیر آن قرار دارد نادیده میگیرد.
SBIS  p,b این دستور یک بیت از یک ثبات I/O را بررسی کرده، درصورت یک بودن آن بیت، دستوری را که درست زیر آن قرار دارد نادیده میگیرد.

درباره ی احسان عبداللهی

احسان عبداللهی هستم | کارشناسی الکترونیک خوندم و کارشناسی ارشد مخابرات |در سال 94 وب سایت میکرولرن را راه اندازی کردم | سعی کردم هر چیزی را به صورت کاربردی دنبال کنم، برای همین از کارشناسی کار با میکروکنترلرهای AVR و ARM، برنامه نویسی C و طراحی PCB را به صورت تخصصی کار کردم و از کارشناسی ارشد برنامه نویسی پایتون ، Computer vision و deep learning را به صورت تخصصی و کاربردی شروع کردم | الان هم سعی میکنم همیشه خودم را به روز نگه دارم و لذت کار کردن با دنیای برنامه نویسی و امبدد سیستم ها را به دیگران انتقال بدم

۲ دیدگاه

  1. سلام می شه در مورد تفاوت rcallوrjmpبیشتر توضیح بدید…تفاوت این دوتا چیه دقیقا…اگه می شه برام ایمیل کنید

    • با سلام
      دستور rcall برای فراخوانی توابع هست و دستور rjmp مربوط به پرش به نقطه خاصی از برنامه میشه. میتونید کتاب دکتر مزیدی را مطالعه کنید تا اطلاعات بیشتری به دست بیارید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *