در قسمت قبل دستورهای جدیدی را برای شبیهساز تعریف کردیم و در این قسمت تمام دستورهای باقیمانده مربوط به این میکروکنترلر را تعریف میکنیم.
این دستور مقدار رجیستر W را از رجیستر F کم میکند (F – W) و درصورتیکه مقدار d برابر با 1 یا F باشد نتیجه در رجیستر F ذخیره میشود در غیر این صورت، اگر مقدار d برابر با 0 یا W باشد نتیجه در رجیستر W ذخیره میشود.
درصورتیکه نتیجه کوچکتر از 0 (منفی) شد بیت C یا Carry در رجیستر STATUS برابر با 0 میشود، در غیر این صورت Carry برابر با 1 میباشد و نتیجه برابر با 0 میشود.
درصورتیکه نتیجه دستور برابر با 0 بود بیت Z مربوط به رجیستر STATUS برابر با 1 میشود.
این دستور مکان چهار بیت اول را با چهار بیت دوم جابهجا میکند.
برای مثال اگر مقدار رجیستر F بهصورت باینری برابر با 0b11110000 باشد بعد از انجام عملیات مقدار آن بهصورت 0b00001111 درمیآید.
اگر مقدار d برابر با 1 یا F بود مقدار نتیجه در رجیستر F ذخیره میشود، در غیر این صورت اگر مقدار d برابر با 0 یا W بود مقدار آن در رجیستر W ذخیره میشود.
این دستور مقدار رجیستر داده شده را به مقصد مشخص شده میبرد!
اگر مقدار d برابر با 1 یا F بود مقدار در خودش ذخیره می شود در غیر این صورت اگر مقدار d برابر با 0 یا W بود مقدار، در رجیستر W ذخیره می شود.
ذخیره مقدار در خود زمانی مفید میباشد که نیاز داریم بین Z مربوط به رجیستر STATUS را بررسی کنیم بدون دستکاری بقیه مقدارها!
این دستور مقدار رجیستر F را با مقدار رجیستر W بهصورت Exclusive OR (^) حساب میکند!
اگر مقدار d برابر با 0 یا W بود نتیجه در رجیستر W ذخیره میشود، در غیر این صورت اگر مقدار d برابر با 1 یا F بود نتیجه در رجیستر F ذخیره میشود.
این دستور روی بیت Z مربوط به رجیستر STATUS تأثیر میگذارد، اگر نتیجه عملیات برابر با 0 شد بیت Z برابر با 1 می شود در غیر این صورت مقدار این بیت برابر با 0 می شود.
این دستور همانند دستور ANDWF میباشد و عملیات AND را انجام میدهد، با این تفاوت که برعکس دستور ANDWF این دستور یک مقدار literal یا عددی را دریافت میکند و عملیات AND را با مقدار دریافتی و مقدار رجیستر W انجام میدهد و در نهایت نتیجه را در رجیستر W ذخیره میکند!
این دستور نیز روی بیت Z در رجیستر STATUS تأثیر میگذارد و درصورتیکه نتیجه عملیات برابر با 0 شد این بیت برابر با 1 میشود در غیر این صورت مقدار بیت Z برابر با 0 میشود.
این دستور رفتاری شبیه به دستور GOTO دارد و مقدار PC را به مکان داده شده (k) تغییر میدهد، اما قبل از این کار آدرس دستور بعدی خود را در یک STACK ذخیره میکند که به کد مربوط به این بخش بعداً میپردازیم!
این دستور همانند دستور MOVLW مقدار عددی k را در رجیستر W ذخیره میکند، با این تفاوت که بعد از انجام عملیات آخرین آدرس اضافه شده به STACK را از آن میگیرد و مقدار آن را در PC ذخیره میکند و باعث تغییر شمارنده برنامه میشود؛ همانند GOTO و CALL.
ترکیب دستور های RETLW و CALL بسیار مفید میباشند و به ما اجازه صدازدن بخشی از کد را میدهند (همانند صدازدن توابع)!
این دستور همانند دستور IORWF عملیات OR را انجام میدهد با این تفاوت که این دستور یک مقدار عددی (literal) دریافت میکند و عملیات OR را با مقدار عددی دریافتی و مقدار رجیستر W انجام میدهد و نتیجه را در رجیستر W ذخیره میکند.
این دستور نیز روی بیت Z مربوط به رجیستر STATUS تأثیر میگذارد و درصورتیکه نتیجه عملیات برابر با 0 شد این بیت برابر با 1 میشود و در غیر این صورت مقدار این بیت برابر با 0 میشود.
این دستور همانند دستور XORWF میباشد؛ اما بجای دریافت آدرس یک مقدار عددی (literal) دریافت میکند و عملیات XOR (^) را با مقدار دریافتی و مقدار رجیستر W انجام میدهد.
این دستور برعکس دستور XORWF مقدار d را دریافت نمیکند و مستقیم نتیجه را در رجیستر W ذخیره میکند.
همانند دستورهای قبلی که با رجیستر W سروکار داشتند این دستور نیز روی بیت Z مربوط به رجیستر STATUS تأثیر میگذارد و درصورتیکه نتیجه عملیات برابر با 0 بود مقدار بیت Z برابر با 1 و در غیر این صورت مقدار این بیت برابر با 0 می شود.
این دستور مقدار timer مربوط به CPU را برابر با 0 قرار می دهد.
این دستور مقدار رجیستر OPTION را بارگذاری میکند و مقدار رجیستر W را در آن قرار میدهد.
این دستور فقط دو مقدار 0x06 یا 0x07 را بهعنوان آدرس دریافت میکند و باتوجهبه مقدار رجیستر W بیتهایی که برابر با 0 هستند را به عنوان ورودی و بیت هایی که برابر با 1 هستند را به عنوان خروجی در نظر میگیرد.
و چون که در این میکروکنترلر (PIC10F200) مقدار 0x06 برابر با رجیستر GPIO میباشد این دستور مقدار 0x06 را دریافت میکند.
حالا که با نحوه کارکرد دستورهای جدید آشنا شدیم، زمان بهروزرسانی کدهای مربوط به emulator میباشد.
کدهای زیر را برای تشخیص دستورها به تابعdecode_inst اضافه میکنیم:
بعد از تشخیص دستورها نیاز داریم که آنها را با اجرا کنیم، حالا به بخشهای جدید مربوط به تابع execute میپردازیم:
خطهای بین 51 تا 27 برای آپدیتکردن بیت DC مربوط به رجیستر STATUS میباشد که مقدار آن برابر با 1 است اگر که حاصل عملیات از 0b1111 بیشتر باشد (نیاز به Borrow داشته باشد) در غیر این صورت برابر با 0 میباشد.
میکروکنترلر PIC10F200 دارای اندازه STACK برابر با 2 میباشد، این به این معنی است که ما فقط میتوانیم 2 تابع تو در تو داشته باشیم؛ زیرا که دستور CALL با اندازه 2 برای STACK سر و کار دارد!
این قانون برای دستور RETLW نیز صدق میکند؛ زیرا که این دستور نیز با اندازه 2 برای STACK سر و کار دارد!
کدهای مربوط به اضافهکردن و گرفتن آدرس به stack بهصورت زیر میباشد:
تابع pop_stack آخرین آدرس وارد شده (با استفاده از push_stack) را برمیگرداند اگر بعد از اضافهشدن 2 آدرسی با استفاده از تابع push_stack به مقداری بیشتر از 2 تابع pop_stack را صدا بزنیم آخرین مقدار وارد شده برمیگردد و برابر با 0 نمیشود!
برای مثال اگر آدرسهای 2 و 3 را با استفاده از push_stack به stack وارد کنیم و به تعداد 3 بار تابع pop_stack را صدا بزنیم آدرسهای دریافتی به صورت 3، 2 و 2 میباشد (تبدیل به 0 نمیشود).
با استفاده از این stack میتوان کدی شبیه به صدازدن توابع را در این نوع assembly داشت.
حالا با استفاده از این دو دستور و ایجاد یک حلقه که در پست قبل اشاره شد. برنامهای مینویسیم که مقدار A تا K را نمایش دهد:
نویسنده شو !
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.