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

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

دستورات پرش و روش ایجاد حلقه

در AVR  دو نوع دستور پرش وجود دارد.

۱-دستورات پرش شرطی

پرش در این دستورات بر اساس شرایط خاصی صورت می گیرد که این شرایط را پرچمهای ثبات وضعیت مشخص می کنند.یعنی بر اساس وضعیت بیت های ثبات  SREG پرش صورت می گیرد. از این دستورات برای ایجاد پرش های کوتاه استفاده می شود.این را بدانید که در AVR تمام پرش های شرطی کوتاه هستند.دامنه این پرشها می توانند تا ۱۲۸ بایت از محتوای شمارنده برنامه دورتر باشند.

(BRNE(Branch if not equal:

این دستور از پرچم Z به عنوان شرط برای پرش استفاده می کند.اگر Z=0 باشد پرش انجام می شود و اگر Z=1 باشد پرش صورت نمی گیرد و برنامه از دستور بعد از آن اجرا می شود. از این دستور می توان برای ایجاد دفعات تکرار استفاده کرد.

به مثال زیر توجه کنید: در این مثال R16 پنج بار با R17 جمع شده.دستوراتی وجود دارند که به وسیله آنها می توان از چنین تکرارهایی جلوگیری کرد.

یا

با هر بار اجرا شدن دستور dec R18 یک واحد از مقدار R18 کاسته می شود. تا زمانی که مقدار R18 غیر صفر باشد این روند ادامه پیدا می کند.باصفر شدن مقدار R18 پرچم Z در ثبات وضعیت یک شده و و دیگر پرش صورت نمیگیرد.

با این روش می توان حلقه هایی را در درون یکدیگر تعریف کرد و عملی را با تعداد دلخواه تکرار کنیم.

مثال: در مثال زیر عملیات جمع ۲۵ بار انجام می شود.

دستورات دیگر پرش های شرطی در جدول زیر به صورت خلاصه آمده.

دستور عمل
BRLO اگر C=1 بود، پرش کن.
BRSH اگر C=0 بود، پرش کن.
BREQ اگر Z=1 بود، پرش کن.
BRNE اگر Z=0 بود، پرش کن.
BRMI اگر N=1 بود، پرش کن.
BRPL اگر N=0 بود، پرش کن.
BRVS اگر V=1 بود، پرش کن.
BRVC اگر V=0 بود، پرش کن.

۲- دستورات پرش غیر شرطی

 در پرشهای غیر شرطی کنترلر برنامه بدون هیچ شرط خاصی به محل مقصد انتقال می یابد.

این دستورات عبارتند از (JMP(jump)،RJMP(Relative jump و ( IJMP(Indirect Jump.

JMP یک پرش بلند است که می تواند به هر خانه حافظه در ۴M فضای آدرس AVR برود.این دستور چهاربایتی است.در بعضی از AVR ها که حافظه محدودتری دارند برای صرفه جویی در مصرف حافظه از دستور RJMP که یک دستور ۲ بایتی است استفاده می شود.این دستور همان کار JMP را می کند با این تفاوت که حد اکثر دامنه پرش آن تا ۲ کیلوبایت است.

IJMP یک دستور دو بایتی است که به آدرسی که ثبات اشاره گر Z به آن اشاره می کند پرش میکند.

Z  نام دیگر ثبات های همه منظوره R30 و R31 می باشد که با هم یک اشاره گر ۳۲ بیتی را تشکیل می دهند. در مورد اشاره گرها در جلسات بعدی توضیح داده خواهد شد.

دستورات فراخوانی زیر روال ها

زیر روال ها قطعه برنامه هایی هستند که برای اجرای وظایفی که احتیاج به اجرای مکرر دارند استفاده می شوند(همانند توابع در زبان C).

در AVR چهار دستور( CALL(long call)، RCALL(Relative call)، ICALL(Indirect call to z)، ECALL(extended indirect call to z برای فراخوانی زیر روال ها استفاده می شود.

دستور CALL یک دستور ۴ بایتی است که می تواند زیر روال هایی در محدوده ۴M را را فراخوانی کند.برای صرفه جویی مصرف حافظه در AVR هایی که حافظه محدودتری دارند از دستور RCALL استفاده می شود.این دستور یک دستور ۲ بایتی است که دامنه دسترسی آن حداکثر تا ۲ کیلو بایت است.تفاوتی ندارد که زیرروال قبل و یا بعد از دستور فراخوانی نوشته شود، فقط باید در محدوده دامنه پرش باشد.اما به طور معمول زیرروال ها در آخر برنامه اصلی نوشته می شوند.

مثال:

images

در این مثال عمل جمع در قالب یک زیر روال آمده و برای هربار اجرا شدن کافی است تا آن را با دستورcall ویا rcall فراخوانی کنیم. با هربار فراخوانی یک زیرروال آدرس دستور بعد از آن که یک آدرس ۱۶ بیتی است در دوبایت از پشته به صورت اتوماتیک ذخیره می شود.

دستور(ret(Return که در آخر زیر روال آمده آدرس دستور بعد از فراخوانی تابع را که در هنگام فراخوانی در پشته ذخیره شده از پشته واکشی کرده و در شمارنده برنامه قرار میدهد و کنترلر برنامه را به دستور بعد از فراخوانی برمیگرداند.اگر این دستور در آخر زیرروال ها استفاده نشود کنترلر بعد از اجرای دستورات زیر روال، به دستور بعد از فراخوانی برنمیگردد.

همچنین باید در نوشتن زیر روالها و در استفاده از ثبات ها دقت کرد و برای احتیاط  و جلوگیری از ازدست رفتن  محتویات ثبات های همه منظوره، در اول زیر روال مقدار آنها را با استفاده از دستور push در پشته ذخیره کنیم و در انتهای زیر روال از آخرین ثباتی که push کردیم با استفاده از دستور pop محتویات قبلیشان را از پشته به درون آنها برگردانیم.البته این مورد اختیاری است و به برنامه ای که مینویسید بستگی دارد.

مثال: زیر روال زیر محتویات R1 و R2 را باهم جمع کرده و نتیجه را در R2 قرار می دهد.

 

قواعد برچسب زدن در زبان اسمبلی

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

در برچسب زدن به نکات زیر باید توجه کرد:

اول اینکه نام هر برچسب باید یکتا باشد یعنی در یک برنامه نباید از برچسب های مشابه استفاده کرد.نامی که برای برچسب ها انتخاب می شود نباید با کلماتی که مخصوص اسمبلر است مشابه باشد(مثلا کلمه ADD نمیتواند باشد).

کاراکتر های مورد استفاده در برچسب شامل حروف الفبا(بزرگ و کوچک)، ارقام ۰ تا ۹ و کاراکترهای مخصوص مانند (?),(@),(_),($) تشکیل شده اند.حرف اول هر برچسب حتما باید یکی از حروف الفبا باشد.اسمبلربرای حروف کوچک وبزرگ تفاوتی قائل نمی شود.

Illustration of a wooden tag label with string isolated on white background

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

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

۹ دیدگاه

  1. خوب این رجیستر program counter جز کدام یک از رجیستر هاست؟

    • این رجیستر جزئ رجیسترهای عمومی یا رجیسترهای استاندارد که طول ۸ بیت یا ۱۶ بیت دارند نیست. براساس اینکه حافظه فلش چه مقدار است طول این رجیستر معلوم می شود. مثلا در atmega32 که ۳۲ کیلو بایت حافظه فلش دارد طول این رجیستر ۱۴ بیت میشه. به این توضیح دقت کن تا متوجه بشی. خونه های ROM دو بایتی هستند پس ۳۲کیلوبایت را اگه به ۲ تقسیم کنی. ۱۶ کیلو ورد(Kword) داری. یعنی ۱۶ کیلو خونه ی حافظه. خب با ۱۴ بیت هم به راحتی میتونی ۱۶ کیلو خونه را آدرس دهی کنی.

  2. سلام
    در مثال اول دستورات پرش شرطی اشتباها به جای LDT , LDI نوشته شده است.

    ۱- ۴M فضای حافظه در AVR یعنی چی؟

    ۲-حد اکثر دامنه پرش یعنی چی؟

    • سلام. ایمان از تذکرت ممنون.
      در جواب سوال اولت: cpu در میکروکنترلرها ثباتی دارند به نام شمارنده برنامه که حافظه را آدرس دهی میکنه و دامنه آدرس دهیش بستگی به تعداد بیتش داره.مثلا شما بیا تو ذهنت اینطور تصور کن که کارخانه میاد cpu را به صورت یک قطعه جدا میخره و روی میکرو مونتاژ میکنه. بعد شرکتی که cpu را میسازه میگه من فقط میتونم شمارنده برنامش را تا ۲۲ بیت افزایش بدم .حالا ۲ را به توان ۲۲ کن میشه ۴۱۹۴۳۰۴بایت.یعنی حد اکثر تا حدود ۴ مگابایت را میتونه آدرسدهی کنه. ولی کارخانه میاد برای اینکه هزینش کم بشه برای هر میکرویی به اندازه حافظه بکار رفته مقدار شمارنده برنامه را مشخص میکنه.
      برای جواب سوال دوم یه سری به لینک http://microlearn.ir/461/assembly-language-2.html بزن.

    • سلام ایمان
      سوال اول رو که جلال پاسخ داد.فکر میکنم ابهامت رفع شد. اگه توضیح بیشتری لازم داری بگو تا بیشتر برات توضیح بدم.
      اما سوال دوم :دستورای پرش هر کدومشون تا یک تعداد آدرس مشخصی نسبت به مکان فعلیشون میتونند پرش کنند. مثل همون چهار مگابیت در مثال قبل (۴M). این مقدار را حداکثر دامنه پرش میگن. مثلا حداکثر دامنه پرش دستور RJMP و دستور JMP با هم فرق داره.

      • سوال اول رو اصلا متوجه نشدم .

        الان اگه ۴M رو تقسیم بر ۸ کنیم میشه تعداد ۵۰۰۰۰۰ :یعنی میتونه ۵۰۰۰۰۰ از اینجایی که هست به عقب تر یا جلوتر پرش کنه.بر هشت تقسیم کردم چون هر خونه حافظه ۸ بیتی است.

        • نه نه این اشتباه رو نکن. منظور از ۴M تعداد بیت ها نیست. منظور خونه های حافظه است. هر آدرسی که الان برنامه توی اون هست رو در نظر بگیر. با این پرش میتونی ۴M به سمت بالا یا پایین پرش کنی. میخوام کمی برات توضیح بیشتری بدم تا درک بهتری بدست بیاری. دستور JMP یک دستور ۴ بایتی هست یعنی وقتی اون رو در یک خط از برنامه می نویسی ۴ بایت فضا برای ذخیره سازی لازم داره. حالا از این ۴ بایت یا ۳۲ بیت، ۱۰ بیتش برای کدی هست که معنای پرش داره و ۲۲ بیت باقی مونده همون آدرس خونه ای از حافظه هست که میخوایم بریم به اونجا. با ۲۲ بیت میتونی چند خونه حافظه رو آدرس دهی کنی؟ درسته ۲ به توان ۲۲ که میشه همون ۴M. البته حواست باشه که این حرفایی که میزنیم مربوط به حافظه برنامه (همون حافظه فلش یا ROM) هست. هر کدوم از خونه های این حافظه هم ۲ بایت طول داره. امیدوارم تونسته باشم ابهامتو برطرف کنم. بخون اگه سوال داشتی حتما بازم بپرس

          • سلام متشکرم

            ۱- ادرس دهی در حافظه ROM چطوری هست؟

          • ببین ایمان جان نکته ای که برای آدرس دهی در حافظه ROM وجود داره اینه که این حافظه اولا ۱۶ بیتی یا دو بایتی هست. یعنی هر خونه طولش ۲ بایته. نکته ی دوم اینه که شما با استفاده از رجیستر program counter یا شمارنده برنامه میتونی این حافظه را آدرس دهی کنی. یعنی اون چیزی که در رجیستر pc وجود داره آدرس یکی از خونه های حافظه ROM هست. یه ریزه کاری هم اینجا وجود داره که باید بهش دقت کرد: در زمانی که خط فعلی برنامه داره اجرا میشه ( مثلا خط ۱۰۰، مهم نیست کدوم خط) آدرس خط بعدی برنامه در pc قرار داده شده یعنی به عبارتی pc همیشه به آدرس خط بعدی برنامه که قراره اجرا بشه اشاره می کنه.
            اما شما اصلا درگیر این آدرس دهی ها نمیشی. فقط باید روش کارش رو بلد باشی.

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

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