این ریدمی مربوط به پروژه درسی در زمینه برنامهنویسی پیشرفته با زبان CPP است که تحت نظر دکتر محسن رحمانیان در دانشگاه جهرم انجام شده است. این پروژه یک اسمبلر است که دستورات اسمبلی سفارشی از فایل ورودی در مسیر input.txt
را دریافت کرده و با استفاده از زبان CPP این دستورات را پردازش میکند.
خواندن و پردازش دستورات: این پروژه ابتدا دستورات اسمبلی از فایل ورودی input.txt
را میخواند و آنها را پردازش میدهد.
حذف فضاهای خالی: فضاهای خالی موجود در دستورات را حذف میکند.
مقداردهی اولیه: متغیرها، ثباتها و برچسبها را با کمک یک حافظه 100 کلمهای مجازی مقداردهی اولیه میکند.
اجرای دستورات: دستورات را اجرا کرده و خروجی را در ترمینال نمایش میدهد.
تعامل با کاربر (در صورت نیاز): در صورتی که برنامهها نیاز به تعامل با کاربر و دریافت ورودی از او دارند، این تعامل را انجام میدهد.
این پروژه از یک زبان اسمبلی سفارشی به نام "سیمپلوس" استفاده میکند. سیمپلوس یک زبان اسمبلی سفارشی است که برای شبیهسازی سختافزار مورد نظر (که در این پروژه به صورت مجازی شبیهسازی شده است) طراحی شده است. دستورات و ثابتهای این زبان در ادامه به طور کامل توضیح داده شدهاند.
ماشین سیمپلوس دارای اجزای زیر است:
- واحد کنترل مرکزی (CPU)
- حافظه ۱۰۰ کلمهای
- صفحه کلید به عنوان دستگاه ورودی
- صفحه نمایش به عنوان خروجی
- قلب سیمپلوس که مجموعهای محدود از عملیات ساده را انجام میدهد.
- مراحل عملیاتی:
- عددی که در ثبات شمارنده دستور (PC) هست را میخواند.
- به حافظهای با شمارهی خوانده شده مراجعه کرده و دستورالعمل قرار داده شده در آن را در ثبات دستورالعمل (IS) کپی میکند.
- یکی به مقدار ثبات شمارنده دستور اضافه میکند.
- دستورالعمل موجود در ثبات IS را اجرا میکند.
- به مرحله یک برمیگردد.
- واحد پردازش مرکزی (CPU) شامل ثباتهای زیر میباشد:
- ثبات PC: ثبات شمارنده برنامه
- ثبات IS: ثبات دستورالعمل
- ثبات ACC: ثبات انباره
- ثبات FLG: ثبات پرچم
برای این کامپیوتر ۱۰۰ کلمه در یکجا تعبیه شدهاند. هر کلمه معادل یک عدد حیح میباشد. حافظه مربوط به برنامه و دادهها در یکجا تعبیه شده است. یعنی حافظه دادهها بلافاصله بعد از فضای برنامه شروع میشود.
همه درستوالعملهای ماشین سیمپلوس عدد صحیح بوده و به یکی از صورتهای زیر استفاده میشوند:
- نوع اول:
- ۵ دستور کد دستورالعمل، ۱۱ دستور کد پرکننده
- نوع دوم:
- ۵ دستور کد دستورالعمل، ۱۱ دستورهای اضافی
که در آن آدرس عدد صحیح ۱۱ بیتی و بدون علامت است. دستورالعملهای ماشین سیمپلوس به همراه معنای هر یک از آنها در جدول زیر آمده است. زبان اسمبلی یک زبان برنامهنویسی سطح پائین است که به جای کدهای دستورالعمل عددی از حفظیات و برچسبها استفاده میکند.
توضیحات | دستورالعمل | کد حفظی | کد عددی |
---|---|---|---|
مقدار ذخیره شده در حافظه xx را به مقدار موجود در انباره اضافه می کند. نکته: محتوای حافظه تغییر نمی کند، و عمل های انباره برای دستورالعمل های جمعی که جمع های بیشتر از ۳ را انجام می دهند، تعریف نشده اند. به طور مشابه برای تفریق، می توان یک پرچم منفی بر روی سرریز در نظر گرفت. |
ADD | ADD | 01xx |
ﻣﻘﺪﺍﺭ ﺫﺧﯿﺮﻩ ﺷﺪﻩ ﺩﺭ ﺣﺎﻓﻈﻪ xx ﺭﺍ ﺍﺯ ﻣﻘﺪﺍﺭ ﻣﻮﺟﻮﺩ ﺩﺭ ﺍﻧﺒﺎﺭﻩ ﺗﻔﺮﯾﻖ ﻣﯽﮐﻨﺪ. ﻧﮑﺘﻪ: ﻣﺤﺘﻮﺍﯼ ﺣﺎﻓﻈﻪ ﺗﻐﯿﯿﺮ ﻧﻤﯽﮐﻨﺪ. |
SUBTRACT | SUB | 02xx |
ﻣﻘﺪﺍﺭ ﺫﺧﯿﺮﻩ ﺷﺪﻩ ﺩﺭ ﺣﺎﻓﻈﻪ xx ﺭﺍ ﺩﺭ ﻣﻘﺪﺍﺭ ﻣﻮﺟﻮﺩ ﺩﺭ ﺍﻧﺒﺎﺭﻩ ﺿﺮﺏ ﻣﯽﮐﻨﺪ. ﻧﮑﺘﻪ: ﻣﺤﺘﻮﺍﯼ ﺣﺎﻓﻈﻪ ﺗﻐﯿﯿﺮ ﻧﻤﯽﮐﻨﺪ. |
MULTIPLY | MULT | 03xx |
ﻣﻘﺪﺍﺭ ﺫﺧﯿﺮﻩ ﺷﺪﻩ ﺩﺭ ﺣﺎﻓﻈﻪ xx ﺭﺍ ﺑﺮ ﻣﻘﺪﺍﺭ ﻣﻮﺟﻮﺩ ﺩﺭ ﺍﻧﺒﺎﺭﻩ ﺗﻘﺴﯿﻢ ﻣﯽﮐﻨﺪ. ﻧﮑﺘﻪ: ﺩﺭﺻﻮﺭﺕ ﺑﺮﻭﺯ ﺗﻘﺴﯿﻢ ﺑﺮ ﺻﻔﺮ FⅬG ﺑﺎ ﻣﻘﺪﺍﺭ ۱ ﭘﺮ ﻣﯽﺷﻮﺩ. |
DIVISION | DIV | 04xx |
ﺫﺧﯿﺮﻩ ﻣﻘﺎﺩﯾﺮ ﻣﻮﺟﻮﺩ ﺩﺭ ﺍﻧﺒﺎﺭﻩ ﺩﺭ ﺣﺎﻓﻈﻪxx(ﻣﺨﺮﺏ). ﻧﮑﺘﻪ: ﻣﻘﺎﺩﯾﺮ ﺍﻧﺒﺎﺭﻩ ﺑﺪﻭﻥ ﺗﻐﯿﯿﺮ ﺑﺎﻗﯽ ﻣﯽﻣﺎﻧﻨﺪ (ﺗﺨﺮﯾﺐ ﻧﻤﯽﺷﻮﻧﺪ)، ﺍﻣﺎ ﻣﻘﺎﺩﯾﺮ ﺣﺎﻓﻈﻪ ﯾﺎ ﻣﻘﺪﺍﺭﯼ ﮐﻪ ﺩﺭ ﺁﻧﺠﺎ ﺑﻮﺩﻩ ﺟﺎﯾﮕﺰﯾﻦ ﻣﯽﺷﻮﻧﺪ (ﺗﺨﺮﯾﺐ ﻣﯽﺷﻮﻧﺪ). |
STORE | STA | 05xx |
ﻣﻘﺪﺍﺭ ﺣﺎﻓﻈﻪ xx ﺭﺍ ﺑﺎﺭﮔﺬﺍﺭﯼ ﻣﯽﮐﻨﺪ (ﺍﺯ ﺑﯿﻦ ﻧﻤﯽﺑﺮﺩ) ﻭ ﺁﻥ ﺭﺍ ﺑﻪ ﺍﻧﺒﺎﺭﻩ ﻭﺍﺭﺩ ﻣﯽﮐﻨﺪ (ﺍﺯ ﺑﯿﻦ ﻣﯽﺑﺮﺩ). | LOAD | LDA | 06xx |
ﺷﻤﺎﺭﻧﺪﻩ ﺑﺮﻧﺎﻣﻪ ﺭﺍ ﺑﻪ ﺁﺩﺭﺱ ﺩﺍﺩﻩ ﺷﺪﻩ ﺗﻨﻈﯿﻢ ﻣﯽﮐﻨﺪ (ﻣﻘﺪﺍﺭ xx) . ﯾﻌﻨﯽ ﻣﻘﺪﺍﺭ xx ﺩﺳﺘﻮﺭﺍﻟﻌﻤﻞ ﺑﻌﺪﯼ ﺧﻮﺍﻫﺪ ﺑﻮﺩ ﮐﻪ ﺍﺟﺮﺍ ﻣﯽﺷﻮﺩ. | BRANCH ALWAYS | BRA | 07xx |
ﺍﮔﺮ ﻣﻘﺪﺍﺭ ﺍﻧﺒﺎﺭﻩ ﺑﺮﺍﺑﺮ ﺑﺎ ﺻﻔﺮ ﺑﻮﺩ، ﺷﻤﺎﺭﻧﺪﻩ ﺑﺮﻧﺎﻣﻪ ﺭﺍ ﺑﺮﺍﺑﺮ ﻣﻘﺪﺍﺭ xx ﻗﺮﺍﺭ ﺑﺪﻩ. ﺩﺭ ﻏﯿﺮ ﺍﯾﻦ ﺻﻮﺭﺕ ﻫﯿﭻ ﻋﻤﻠﯽ ﺍﻧﺠﺎﻡ ﻧﺪﻩ. ﻧﮑﺘﻪ: ﺗﺎ ﺯﻣﺎﻧﯽ ﮐﻪ ﺑﺮﻧﺎﻣﻪ ﺩﺭ ﺣﺎﻓﻈﻪ ﺫﺧﯿﺮﻩ ﻣﯽﺷﻮﺩ، ﺗﻤﺎﻣﯽ ﺩﺍﺩﻩﻫﺎ ﻭ ﺩﺳﺘﻮﺭﺍﻟﻌﻤﻞﻫﺎﯼ ﺑﺮﻧﺎﻣﻪ ﻓﺮﻣﺖ ﺁﺩﺭﺱ̸ﻣﮑﺎﻥ ﯾﮑﺴﺎﻧﯽ ﺩﺍﺭﻧﺪ. |
BRANCH IF ZERO | BRZ | 08xx |
ﺍﮔﺮ ﻣﻘﺪﺍﺭ ﺍﻧﺒﺎﺭﻩ ﻣﺜﺒﺖ ﺑﺎﺷﺪ، ﺷﻤﺎﺭﻧﺪﻩ ﺑﺮﻧﺎﻣﻪ ﺑﺮ ﺭﻭﯼ xx ﺗﻨﻈﯿﻢ ﻣﯽﺷﻮﺩ. ﺩﺭ ﻏﯿﺮ ﺍﯾﻨﺼﻮﺭﺕ ﻫﯿﭻ ﻋﻤﻠﯽ ﺍﻧﺠﺎﻡ ﻧﻤﯽﺩﻫﺪ. | BRANCH IF POSITIVE | BRP | 09xx |
ﺍﮔﺮ ﻣﻘﺪﺍﺭ ﺍﻧﺒﺎﺭﻩ ﻣﻨﻔﯽ ﺑﺎﺷﺪ، ﺷﻤﺎﺭﻧﺪﻩ ﺑﺮﻧﺎﻣﻪ ﺑﺮ ﺭﻭﯼ xx ﺗﻨﻈﯿﻢ ﻣﯽﺷﻮﺩ. ﺩﺭ ﻏﯿﺮ ﺍﯾﻨﺼﻮﺭﺕ ﻫﯿﭻ ﻋﻤﻠﯽ ﺍﻧﺠﺎﻡ ﻧﻤﯽﺩﻫﺪ. | BRANCH IF NEGATIVE | BRN | 10xx |
ﺍﮔﺮ ﻣﻘﺪﺍﺭ ﺛﺒﺎﺕ ﭘﺮﭼﻢ ﯾﮏ ﺑﺎﺷﺪ، ﺷﻤﺎﺭﻧﺪﻩ ﺑﺮﻧﺎﻣﻪ ﺑﺮ ﺭﻭﯼ xx ﺗﻨﻈﯿﻢ ﻣﯽﺷﻮﺩ. ﺩﺭ ﻏﯿﺮ ﺍﯾﻨﺼﻮﺭﺕ ﻫﯿﭻ ﻋﻤﻠﯽ ﺍﻧﺠﺎﻡ ﻧﻤﯽﺩﻫﺪ. | BRANCH IF FLAGS | BRG | 11xx |
ﺑﺮﻭ ﺑﻪ ﺻﻨﺪﻭﻕ ﻭﺭﻭﺩﯼ، ﻣﻘﺪﺍﺭ ﺭﺍ ﺍﺯ ﮐﺎﺭﺑﺮ ﺩﺭﯾﺎﻓﺖ ﮐﻦ، ﻭ ﺩﺭ ﺍﻧﺒﺎﺭﻩ ﻗﺮﺍﺭ ﺑﺪﻩ. ﻧﮑﺘﻪ: ﺍﯾﻦ ﻋﻤﻞ ﺑﺎﻋﺚ ﺑﺎﺯﻧﻮﯾﺴﯽ ﻫﺮ ﻣﻘﺪﺍﺭﯼ ﮐﻪ ﺩﺍﺧﻞ ﺍﻧﺒﺎﺭﻩ ﺑﻮﺩﻩﺍﺳﺖ ﻣﯽﺷﻮﺩ (ﻣﺨﺮﺏ). |
INPUT | INP | 1201 |
ﻣﻘﺪﺍﺭ ﺭﺍ ﺍﺯ ﺍﻧﺒﺎﺭﻩ ﺑﻪ ﺻﻨﺪﻭﻕ ﺧﺮﻭﺟﯽ ﮐﭙﯽ ﮐﻦ. ﻧﮑﺘﻪ: ﻣﺤﺘﻮﺍﯼ ﺍﻧﺒﺎﺭﻩ ﺗﻐﯿﯿﺮ ﻧﻤﯽﮐﻨﺪ (ﻏﯿﺮ ﻣﺨﺮﺏ). |
OUTPUT | OUT | 1202 |
برنامه را پایان بده. | HALT | HLT | 0000 |
ﺍﯾﻦ ﯾﮏ ﺩﺳﺘﻮﺭ ﺍﺳﻤﺒﻠﯽ ﺍﺳﺖ ﮐﻪ ﺑﻪ ﺳﺎﺩﮔﯽ ﻣﻘﺪﺍﺭ ﺭﺍ ﺩﺭﻭﻥ ﺣﺎﻓﻈﮥ ﺩﺭﺩﺳﺘﺮﺱ ﺑﻌﺪﯼ ﺑﺎﺭ ﻣﯽﮐﻨﺪ. ﻫﻤﭽﻨﯿﻦ ﻣﯽﺗﻮﺍﻧﺪ ﺩﺭ ﺗﻠﻔﯿﻖ ﺑﺎ ﺑﺮﭼﺴﺐﻫﺎ ﺑﺮﺍﯼ ﺗﻌﺮﯾﻒ ﻣﺘﻐﯿﺮﻫﺎ ﺍﺳﺘﻔﺎﺩﻩ ﺷﻮﺩ. |
DATA | DAT |
اگرچه سیمپلوس تنها از یک دسته محدود از حفظیات استفاده میکند، اما راحتی استفاده از یک حفظی برای هر دستورالعمل از زبان اسمبلی (که در زیر نشان داده شده است) سادگی کار را روشن میکند.
ﺩﺭ ﺯﯾﺮ ﭼﻨﺪ ﻣﺜﺎﻝ ﺍﺯ ﺑﺮﻧﺎﻣﻪ ﺑﻪ ﺯﺑﺎﻥ ﺍﺳﻤﺒﻠﯽ ﺳﯿﻤﭙﻠﺲ ﺁﻣﺪﻩ ﺍﺳﺖ:
ﺑﺮﻧﺎﻣﻪ ﺯﯾﺮ ﻗﺮﺍﺭ ﺍﺳﺖ ﺩﻭ ﻋﺪﺩ ﺭﺍ ﺍﺯ ﮐﺎﺭﺑﺮ ﺩﺭﯾﺎﻓﺖ ﮐﺮﺩﻩ ﻭ ﺣﺎﺻﻞ ﺗﻔﺮﯾﻖ ﺁﻧﻬﺎ ﺭﺍ ﺩﺭ ﺧﺮﻭﺟﯽ ﻧﻤﺎﯾﺶ ﺩﻫﺪ:
INP
STA FIRST
INP
STA SECOND
LDA FIRST
SUB SECOND
OUT
HLT
FIRST DAT
SECOND DAT
ﺧﺮﻭﺟﯽ برنامه:
INPUT | OUTPUT |
---|---|
5 | -2 |
7 |
ﻣﺜﺎﻝ ﺯﯾﺮ ﻋﺪﺩ ﻣﺜﺒﺘﯽ ﺭﺍ ﺍﺯ ﮐﺎﺭﺑﺮ ﺩﺭﯾﺎﻓﺖ ﮐﺮﺩﻩ ﻭ ﺍﺯ ﺁﻥ ﻋﺪﺩ ﺗﺎ ﺻﻔﺮ ﺭﺍ ﺩﺭ ﺧﺮﻭﺟﯽ ﻧﻤﺎﯾﺶ ﻣﯽﺩﻫﺪ:
INP
OUT
LOOP BRZ QUIT
SUB ONE
OUT
BRA LOOP
QUIT HLT
ONE DAT 1
ﺧﺮﻭﺟﯽ:
INPUT | OUTPUT |
---|---|
5 | 5 |
4 | |
3 | |
2 | |
1 | |
0 |
ﺑﺮﻧﺎﻣﻪ ﺯﯾﺮ ﺩﻭ ﻣﻘﺪﺍﺭ ﺻﺤﯿﺢ ﺭﺍ ﺍﺯ ﮐﺎﺭﺑﺮ ﺩﺭﯾﺎﻓﺖ ﮐﺮﺩﻩ . ﻣﻘﺪﺍﺭ ﺑﯿﺸﯿﻨﮥ ﺁﻧﻬﺎ ﺭﺍ ﺩﺭ ﺧﺮﻭﺟﯽ ﻧﻤﺎﯾﺶ ﻣﯽﺩﻫﺪ:
INP
STA num1
INP
STA num2
SUB num1
BRP pos
LDA num1
OUT
BRA exit
pos LDA num2
OUT
exit HLT
num1 DAT
num2 DAT
ﺧﺮﻭﺟﯽ:
INPUT | OUTPUT |
---|---|
5 | 7 |
7 |
ﺑﺮﻧﺎﻣﻪ ﺯﯾﺮ ﺩﻩ ﻋﺪﺩ ﺍﻭﻝ ﻣﺜﻠﺜﯽ ﺭﺍ ﺩﺭ ﺧﺮﻭﺟﯽ ﻧﻤﺎﯾﺶ ﻣﯽﺩﻫﺪ:
loop LDA number
ADD counter
OUT
STA number
LDA counter
ADD one
STA counter
LDA ten
SUB counter
BRP loop
HLT
counter DAT 1
number DAT 0
one DAT 1
ten DAT 10
ﺧﺮﻭﺟﯽ:
INPUT | OUTPUT |
---|---|
1 | |
3 | |
6 | |
10 | |
15 | |
28 | |
36 | |
45 | |
55 |
ﺑﺮﻧﺎﻣﻪ ﺯﯾﺮ ﻋﺪﺩﯼ ﺭﺍ ﺍﺯ ﮐﺎﺭﺑﺮ ﺩﺭﯾﺎﻓﺖ ﮐﺮﺩﻩ ﺳﭙﺲ ﻣﮑﻌﺐ ﺁﻧﺮﺍ ﺭﺍ ﺩﺭ ﺧﺮﻭﺟﯽ ﻧﻤﺎﯾﺶ ﻣﯽﺩﻫﺪ ﻭ ﺍﯾﻦ ﮐﺎﺭ ﺭﺍ ﺗﺎ ﺯﻣﺎﻧﯽ ﮐﻪ ﮐﺎﺭﺑﺮ ﻋﺪﺩ ﺻﻔﺮ ﻭﺍﺭﺩ ﻧﮑﺮﺩﻩ ﺍﺩﺍﻣﻪ ﻣﯽﺩﻫﺪ:
START LDA ONE
STA RESULT
STA COUNT
INP
BRZ END
STA VALUE
LOOP LDA RESULT
MUL VALUE
STA RESULT
LDA COUNT
ADD ONE
STA COUNT
SUB TIMES
BRZ ENDLOOP
BRA LOOP
ENDLOOP LDA RESULT
OUT
BRA START
END HLT
RESULT DAT
COUNT DAT
TIMES DAT 3
ONE DAT 1
VALUE DAT
ZERO DAT
ﺧﺮﻭﺟﯽ:
INPUT | OUTPUT |
---|---|
4 | 64 |
2 | 8 |
3 | 27 |
0 |
توضیحات تکمیلی و با جزئیات بیشتر نظیر کامنت به زبان انگلیسی برای کدهای بالا که به عنوان مثال قرار گرفته شده اند در فایل simplus.pdf در دسترس میباشد.
اگر هرگونه پیشنهاد یا سوالی در مورد پروژه دارید یا مایل به بهینهسازی و اضافه کردن فیچرهای بیشتر به این پروژه هستید میتوانید با ارسال یک ایمیل به آدرس زیر با من در ارتباط باشید.
امیدوارم این پروژه برایتان موثر و مفید باشد.