پاسخ : نکته ای در کدنویسی
با سلام خدمت استاد کی نژاد عزیز و دوستان محترم
مطلبی که به ذهن بنده میرسد این است:
با توجه به اینکه متغیر delay از نوع unsigned int تعریف شده و دو بایت از حافظه را اشغال میکند فلذا در زمان مقایسه با مقدار صفر ((while(delay) عملا مقدار low byte در یکی از رجیسترهای R0 الی R31 لود میشود و سپس مقدار high byte در یکی دیگر از رجیسترهای مذکور(به انتخاب کامپایلر) و سپس برای مقایسه با عدد ثابت صفر ابتدا مقدار رجیستر مربوط به low byte با عدد صفر مقایسه می شوذ و در کلاک بعدی مقدار رجیستر مربوط به high byte با عدد صفر مقایسه می شود و سپس با یک دستور branch , بسته به نتیجه مقایسه قبلی که نتیجه آن فلگهای مشخصی را تحت تاثیر قرار میدهد , دستور branch اجرا می گردد یا نمیگردد.
حال فرض کنیم program counter بر روی دستور while(delay مانده و وقفه مربوطه نیز یکی پس از دیگری رخ میدهد و باعث کاهش مقدار متغییر delay می گردد و در آخرین وقفه مقدار delay صفر شده است و در حین اجرای دستور while ( پس از اجرای دستور اسمبلی مربوط به لود کردن رجیستر مربوط به low byte ) دوباره وقفه رخ دهد , چون قبلا مقدار متغیر صفر بوده است فلذا با کاهش یک واحدی دوباره مقدار متغیر, عملا مقدار آن به ماکزیمم مقدار خود یعنی 65535 تغییر حالت میدهد و پس از خاتمه وقفه, عملا program counter به آخرین محلی که قبلا بوده بر میگردد و به اجرای دستور اسمبلی مربوط به لود کردن رجیستر مربوط به high byte می پردازد و با توجه به اینکه مقدار محتوای متغیر قبلا در روتین وقفه دستکاری شده بود , عملا دوباره اجرای برنامه بر روی دستور while(delay می ماند .
برای چلوگیری از این مشکل هم میتوان قبل از دستور while(delay وقفه ها را غیر فعال کرد و بعد از آن دوباره فعال کرد و یا شرط مقایسه با مقدار غیر صفر را در داخل خود وقفه قرار داد و پس از صفر شدن آن با ست کردن یک فلگ به حلقه اصلی برنامه فهماند که تاخیر مورد نظر سپری شده است
با سلام خدمت استاد کی نژاد عزیز و دوستان محترم
مطلبی که به ذهن بنده میرسد این است:
با توجه به اینکه متغیر delay از نوع unsigned int تعریف شده و دو بایت از حافظه را اشغال میکند فلذا در زمان مقایسه با مقدار صفر ((while(delay) عملا مقدار low byte در یکی از رجیسترهای R0 الی R31 لود میشود و سپس مقدار high byte در یکی دیگر از رجیسترهای مذکور(به انتخاب کامپایلر) و سپس برای مقایسه با عدد ثابت صفر ابتدا مقدار رجیستر مربوط به low byte با عدد صفر مقایسه می شوذ و در کلاک بعدی مقدار رجیستر مربوط به high byte با عدد صفر مقایسه می شود و سپس با یک دستور branch , بسته به نتیجه مقایسه قبلی که نتیجه آن فلگهای مشخصی را تحت تاثیر قرار میدهد , دستور branch اجرا می گردد یا نمیگردد.
حال فرض کنیم program counter بر روی دستور while(delay مانده و وقفه مربوطه نیز یکی پس از دیگری رخ میدهد و باعث کاهش مقدار متغییر delay می گردد و در آخرین وقفه مقدار delay صفر شده است و در حین اجرای دستور while ( پس از اجرای دستور اسمبلی مربوط به لود کردن رجیستر مربوط به low byte ) دوباره وقفه رخ دهد , چون قبلا مقدار متغیر صفر بوده است فلذا با کاهش یک واحدی دوباره مقدار متغیر, عملا مقدار آن به ماکزیمم مقدار خود یعنی 65535 تغییر حالت میدهد و پس از خاتمه وقفه, عملا program counter به آخرین محلی که قبلا بوده بر میگردد و به اجرای دستور اسمبلی مربوط به لود کردن رجیستر مربوط به high byte می پردازد و با توجه به اینکه مقدار محتوای متغیر قبلا در روتین وقفه دستکاری شده بود , عملا دوباره اجرای برنامه بر روی دستور while(delay می ماند .
برای چلوگیری از این مشکل هم میتوان قبل از دستور while(delay وقفه ها را غیر فعال کرد و بعد از آن دوباره فعال کرد و یا شرط مقایسه با مقدار غیر صفر را در داخل خود وقفه قرار داد و پس از صفر شدن آن با ست کردن یک فلگ به حلقه اصلی برنامه فهماند که تاخیر مورد نظر سپری شده است
دیدگاه