موضوع مقاله: هک کامپیوتر | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # هک کامپیوتر | مقدمه: هک کامپیوتر هک کامپیوتر یک طراحی نظری کامپیوتر است که توسط نوآم نیسان و شی‌مون شوکن ایجاد شده و در کتاب آن‌ها با عنوان عناصر سیستم‌های محاسباتی: ساخت یک کامپیوتر مدرن از اصول اولیه توضیح داده شده است. | ## بخش 1: هک کامپیوتر | در استفاده از واژه «مدرن»، نویسندگان به یک ماشین دیجیتال و دودویی اشاره دارند که بر اساس مدل معماری فون نویمان طراحی شده است. هک کامپیوتر برای ساخت مجازی عملی در یک برنامه شبیه‌ساز سخت‌افزار طراحی شده و بخشی از یک دوره پایه ولی جامع در سازماندهی و معماری کامپیوتر است. یکی از این دوره‌ها که توسط نویسندگان ایجاد شده و در دو بخش ارائه می‌شود، به‌صورت رایگان در قالب یک دوره آنلاین گسترده (MOOC) تحت عنوان ساخت یک کامپیوتر مدرن از اصول اولیه: از NAND تا تتریس در دسترس است. در دوازده پروژه این دوره، یادگیرندگان از یک گیت نند دو ورودی شروع کرده و در نهایت به یک کامپیوتر مجازی کاملاً عملیاتی می‌رسند، شامل سخت‌افزار (حافظه و CPU) و نرم‌افزار (اسمبلر، ماشین مجازی، زبان برنامه‌نویسی شبیه جاوا و سیستم عامل). علاوه بر شبیه‌ساز سخت‌افزاری که برای پیاده‌سازی اولیه سخت‌افزار کامپیوتر استفاده می‌شود، یک برنامه شبیه‌ساز کامل هک کامپیوتر و اسمبلری که پروژه‌های توصیف‌شده در کتاب و دوره آنلاین را پشتیبانی می‌کند نیز در وب‌سایت نویسندگان در دسترس است. از آنجا که داده‌ها توسط کامپیوتر به‌صورت کلمات ۱۶ بیتی منتقل و پردازش می‌شوند، کامپیوتر Hack به عنوان معماری ۱۶ بیتی طبقه‌بندی می‌شود. حافظه دستورالعمل‌ها، که از دید کامپیوتر به صورت حافظه فقط خواندنی (ROM) پیاده‌سازی شده است، کد برنامه باینری مونتاژ شده برای اجرا را نگه می‌دارد. حافظه دسترسی تصادفی (RAM) فضایی برای ذخیره داده‌های برنامه در حال اجرا فراهم می‌کند و خدمات و مناطق ذخیره‌سازی برای مکانیزم ورودی/خروجی نقشه‌برداری‌شده در حافظه کامپیوتر ارائه می‌دهد. باس‌های آدرس (۱۵ بیتی) و همچنین باس‌های داده و دستورالعمل (۱۶ بیتی) برای واحدهای ROM و RAM کاملاً مستقل هستند. بنابراین، طراحی Hack از نظر ارتباط باس بین واحدهای حافظه و CPU، از مدل معماری هاروارد پیروی می‌کند. تمامی حافظه فقط به صورت آدرس‌دهی بر اساس کلمه قابل دسترسی است حافظه فقط‌خواندنی (ROM) ماژول ROM کامپیوتر Hack به صورت یک آرایه خطی از ثبات‌های حافظه ۱۶ بیتی متوالی و قابل آدرس‌دهی جداگانه ارائه شده است. از آنجا که عناصر حافظه دستگاه‌های متوالی هستند، سیگنال ساعت سیستم توسط برنامه شبیه‌ساز و برنامه شبیه‌ساز کامپیوتر تأمین می‌شود. باس آدرس ROM عرض ۱۵ بیت دارد، بنابراین در مجموع ۳۲٬۷۶۸ کلمه جداگانه برای دستورالعمل‌های برنامه در دسترس است. مقدار موجود در ثبات حافظه ROM که توسط آدرس قرار داده‌شده روی باس آدرس دستورالعمل در یک سیکل ساعت مشخص شده، به عنوان دستورالعمل «فعلی» در ابتدای سیکل بعدی در دسترس قرار می‌گیرد. در این سیستم ثبات دستورالعمل وجود ندارد؛ دستورالعمل‌ها در هر سیکل از ثبات ROM فعال فعلی رمزگشایی می‌شوند. حافظه دسترسی تصادفی (RAM) ماژول RAM نیز به صورت یک آرایه خطی متوالی از ثبات‌های حافظه ۱۶ بیتی خواندنی-نوشتنی و قابل آدرس‌دهی جداگانه پیاده‌سازی شده است، اما از نظر عملکردی به سه بخش تقسیم شده است: آدرس‌های ۰ (۰x۰۰۰۰) تا ۱۶۳۸۳ (۰x۳FFF): شامل ثبات‌های ۱۶ بیتی خواندنی-نوشتنی مرسوم هستند و برای ذخیره داده‌های عمومی برنامه طراحی شده‌اند. آدرس‌های ۱۶۳۸۴ (۰x۴۰۰۰) تا ۲۴۵۷۵ (۰x۵FFF): مشابه RAM داده هستند اما برای استفاده توسط زیرسیستم ورودی/خروجی صفحه‌نمایش داخلی اختصاص داده شده‌اند. داده‌های نوشته شده به این محدوده باعث ایجاد خروجی روی صفحه‌نمایش مجازی ۲۵۶×۵۱۲ می‌شوند. در صورت عدم نیاز برنامه به خروجی صفحه، می‌توان از این ثبات‌ها برای ذخیره داده‌های عمومی استفاده کرد. آدرس ۲۴۵۷۶ (۰x۶۰۰۰): شامل یک ثبات یک‌کلمه‌ای است که مقدار فعلی آن توسط خروجی کیبورد متصل به کامپیوتری که برنامه شبیه‌ساز Hack را اجرا می‌کند، کنترل می‌شود. پیچیده‌ترین عنصر CPU، واحد حسابی-منطقی (ALU) است که محاسبات کامپیوتر را انجام می‌دهد. محاسبات تولید شده به عنوان خروجی از ورودی‌ها توسط مجموعه‌ای از شش ورودی تک‌بیتی ترتیب‌دار مشخص می‌شوند. همچنین ALU دو پرچم وضعیت تک‌بیتی ارائه می‌دهد که نشان می‌دهند آیا نتیجه محاسبه صفر است (پرچم zr) یا منفی (پرچم ng). ثبات A (Address): می‌تواند مقدار فعلی خود را به عنوان ورودی y به ALU ارائه دهد و همچنین برای آدرس‌دهی حافظه داده و به عنوان آدرس هدف دستورهای شاخه‌ای در حافظه دستورالعمل استفاده شود. برای این منظور، ثبات A به یک «ثبات شبه» به نام M مرتبط است که به‌طور مستقیم پیاده‌سازی نشده است و نمایانگر مقداری است که در RAM و در آدرسی که مقدار فعلی A مشخص می‌کند، نگهداری می‌شود. PC یک شمارنده باینری ۱۶ بیتی است که ۱۵ بیت پایین آن آدرس دستورالعمل بعدی در حافظه دستورالعمل را مشخص می‌کند. CPU همچنین شامل منطق تغییر ترتیب اجرای دستورالعمل‌ها تحت کنترل برنامه است تا PC به مقدار غیرمتوالی تنظیم شود. برخلاف بسیاری از طراحی‌های واقعی CPU، هیچ مکانیزم سخت‌افزاری قابل دسترسی برنامه برای وقفه‌های داخلی یا خارجی و پشتیبانی از فراخوانی توابع ارائه نشده است. ورودی و خروجی خارجی (I/O) کامپیوتر Hack از روش نقشه‌برداری حافظه برای ورودی/خروجی استفاده می‌کند. خروجی سیاه و سفید بیت‌مپ شده به صفحه‌نمایش مجازی 256×512 با نوشتن یک بیت‌مپ از خروجی موردنظر در مکان‌های حافظه داده از 16384 (0x4000) تا 24575 (0x5FFF) انجام می‌شود. | ## بخش 2: هک کامپیوتر | کلمات داده در این بازه آدرس به عنوان یک آرایه خطی از بیت‌ها در نظر گرفته می‌شوند که هر بیت نمایانگر وضعیت سیاه/سفید یک پیکسل بر روی صفحه‌نمایش مجازی شبیه‌ساز کامپیوتر است. کم‌ارزش‌ترین بیت کلمه در اولین آدرس حافظه بخش RAM صفحه، پیکسل در گوشه بالای سمت چپ صفحه را سفید می‌کند اگر مقدار آن 0 باشد و سیاه اگر 1 باشد. بیت بعدی با ارزش بیشتر در همان کلمه، پیکسل بعدی به سمت راست را کنترل می‌کند و به همین ترتیب ادامه می‌یابد. پس از آن که اولین ردیف 512 پیکسلی توسط 32 کلمه اول حافظه صفحه توصیف شد، نگاشت به همین صورت برای ردیف دوم با 32 کلمه بعدی ادامه می‌یابد. منطق خارجی کامپیوتر، بخش حافظه RAM صفحه را می‌خواند و صفحه مجازی را به‌روزرسانی می‌کند. اگر یک صفحه‌کلید به کامپیوتری که برنامه شبیه‌ساز CPU را اجرا می‌کند متصل باشد، شبیه‌ساز یک کد اسکن 16 بیتی مربوط به کلیدی که در حین اجرای برنامه فشرده شده است را در ثبات صفحه‌کلید در آدرس RAM 24576 (0x6000) قرار می‌دهد. کدهایی نیز برای سایر کلیدهای معمول در صفحه‌کلید استاندارد ارائه شده است؛ برای مثال کلیدهای کنترل جهت (←، ↑، ↓، →) و کلیدهای Fn. چرخه عملیاتی عملیات مرحله‌به‌مرحله CPU و واحدهای حافظه توسط یک ساعت سیستم (Clock) کنترل می‌شود که در هر دو برنامه شبیه‌ساز سخت‌افزار و شبیه‌ساز کامپیوتر تعبیه شده است. در ابتدای یک سیکل ساعت، دستورالعمل موجود در آدرس ROM که توسط مقدار فعلی شمارنده برنامه (PC) مشخص شده، رمزگشایی می‌شود. اگر شاخه‌ای مشخص شده باشد، PC از مقدار ثبات A بارگذاری می‌شود و آدرس دستورالعمل بعدی برای اجرا در آن قرار می‌گیرد. به دلیل استفاده از مدل معماری حافظه هاروارد، کامپیوتر Hack طوری طراحی شده است که دستورالعمل فعلی را اجرا کرده و دستور بعدی را در یک سیکل ساعت دو قسمتی «دریافت» کند. سرعت ساعت می‌تواند توسط یک عنصر کنترل در هر دو شبیه‌ساز سخت‌افزار و شبیه‌ساز CPU تغییر یابد. با این حال، مستقل از سرعت انتخاب‌شده، هر دستورالعمل به طور کامل در یک سیکل اجرا می‌شود. سپس با بازگرداندن مقدار بیت ریست به 0، اجرای برنامه فعلی از اولین دستور آغاز می‌شود؛ با این حال، حافظه RAM مقادیر باقی‌مانده از فعالیت‌های قبلی قبل از ریست را حفظ می‌کند. نوع داده‌ها مقادیر ذخیره‌شده در حافظه ROM باید دستورالعمل‌های معتبر زبان ماشین Hack را نمایندگی کنند، همان‌طور که در بخش معماری مجموعه دستورالعمل‌ها (ISA) و زبان ماشین توضیح داده شده است. نوع داده مقدار ذخیره‌شده در RAM از مکان آن و/یا کاربردش در برنامه استنتاج می‌شود. برای مقادیری که در ثبات‌های حافظه RAM اختصاص داده‌شده برای ورودی/خروجی صفحه‌نمایش ذخیره می‌شوند، اگر صفحه روشن باشد، مقدار به عنوان نقشه ۱۶ پیکسلی از صفحه مجازی ۲۵۶ ردیف × ۵۱۲ ستون توسط زیرسیستم I/O مستقل کامپیوتر تفسیر می‌شود. مقدار کد ذخیره‌شده در حافظه صفحه‌کلید می‌تواند برنامه‌نویسی شده خوانده شود و برای استفاده در برنامه تفسیر گردد. معماری مجموعه دستورالعمل‌ها (ISA) و زبان ماشین مجموعه دستورالعمل‌ها (ISA) و زبان ماشین مشتق شده از آن در کامپیوتر Hack نسبت به بسیاری از معماری‌های دیگر محدود است. اگرچه ۶ بیت استفاده شده برای مشخص کردن محاسبات توسط ALU می‌تواند ۶۴ دستور متفاوت را مشخص کند، تنها ۱۸ دستور به‌طور رسمی در ISA کامپیوتر Hack پیاده‌سازی شده‌اند. از آنجا که سخت‌افزار Hack از ضرب و تقسیم اعداد صحیح یا فراخوانی توابع پشتیبانی مستقیم ندارد، هیچ دستور زبان ماشین معادل برای این عملیات‌ها در ISA وجود ندارد. • b14–b0 – این ۱۵ بیت نمایانگر نمایش باینری یک عدد صحیح غیرمنفی در بازه ۰ تا ۳۲۷۶۷ هستند. به طور همزمان، ثبات RAM که آدرس آن توسط مقدار دستور مشخص شده است، برای عملیات خواندن یا نوشتن در چرخه کلاک بعدی فعال می‌شود دستورالعمل‌های C (C-instructions) نوع دیگر دستور، دستورالعمل‌های C یا دستورالعمل‌های محاسباتی است که بخش اصلی برنامه‌نویسی را انجام می‌دهد. بیت باارزش‌ترین این دستور برابر با "۱" است و ۱۵ بیت باقی‌مانده به صورت بیت‌فیلد کدگذاری شده‌اند تا ورودی‌ها، محاسبه انجام شده و محل ذخیره خروجی مشخص شوند. این دستور می‌تواند بر اساس نتیجه محاسبه اخیر، عملیات شاخه‌ای (Branch) را نیز مشخص کند. اعلام برچسب‌ها، دستورهای A و C نباید شامل فاصله داخلی باشند، اگرچه فاصله در ابتدا یا انتهای خط مجاز است و نادیده گرفته می‌شود. تمام متن بعد از نماد // تا انتهای خط توسط اسمبلر نادیده گرفته می‌شود و هیچ کد ماشینی تولید نمی‌کند. یک نماد می‌تواند شامل حروف الفبا (بزرگ و کوچک) یا ارقام باشد و می‌تواند شامل _، .، $ و : نیز باشد. اسمبلر زبان اسمبلی Hack برخی نمادهای از پیش تعریف شده را نیز می‌شناسد: • نمادهای R0 تا R15 به ترتیب به اعداد ۰ تا ۱۵ اختصاص دارند و نمایانگر ثبات‌های عمومی هستند؛ بنابراین این نمادها آدرس‌های حافظه داده ۰ تا ۱۵ را مشخص می‌کنند. • نمادهای از پیش تعریف شده دیگر شامل SCREEN و KBD هستند که آدرس شروع صفحه نمایش مجازی (16384) و ورودی صفحه‌کلید (24576) را مشخص می‌کنند. | ## بخش 3: هک کامپیوتر | یک رشته از ارقام ده‌دهی (۰–۹) می‌تواند برای نمایش یک مقدار غیرمنفی در بازه ۰ تا ۳۲۷۶۷ استفاده شود. استفاده از علامت منفی برای اعداد مجاز نیست و نمایش باینری یا هشت‌تایی پشتیبانی نمی‌شود. بنابراین، متغیرها هنگام ظاهر شدن در برنامه باید به عنوان آدرس حافظه در نظر گرفته شوند. در هنگام پردازش توسط اسمبلر، نماد متغیر به یک مقدار صحیح مثبت و یکتا اختصاص داده می‌شود که از آدرس ۱۶ شروع می‌شود. به طور قراردادی، نمادهای تعریف‌شده توسط کاربر که متغیرهای برنامه را مشخص می‌کنند، با حروف کوچک نوشته می‌شوند. برچسب‌ها (Labels) برچسب‌ها نمادهایی هستند که با پرانتز باز و بسته ( ) مشخص می‌شوند. آن‌ها در یک خط جداگانه تعریف شده و توسط اسمبلر به آدرس حافظه دستورالعمل خط بعدی اختصاص داده می‌شوند. برچسب‌ها تنها یک بار می‌توانند تعریف شوند، اما می‌توانند چندین بار در برنامه استفاده شوند، حتی قبل از خطی که در آن تعریف شده‌اند. برچسب‌ها به طور قراردادی با حروف بزرگ نوشته می‌شوند و برای مشخص کردن آدرس هدف دستورهای شاخه‌ای C استفاده می‌شوند. هنگام اجرا، این دستور مقدار ۱۵ بیتی نمایانگر xxxx را در ثبات A و ثبات شبه M بارگذاری می‌کند. تنها راه برای وارد کردن مقدار عددی غیرمنفی به کامپیوتر تحت کنترل برنامه؛ یعنی برای ایجاد ثوابت برنامه استفاده می‌شود. مشخص کردن مکان حافظه RAM با استفاده از مکانیزم ثبات شبه M برای استفاده بعدی توسط دستور C. تعیین آدرس هدف شاخه‌ای در دستور C با استفاده از مقدار فعلی ثبات A، معمولاً با ارجاع به یک برچسب، قبل از دستور شاخه‌ای. • فیلد dest می‌تواند برای مشخص کردن یک یا چند مکان ذخیره نتیجه محاسبه استفاده شود. • فایل خروجی یک فایل متنی است که هر خط آن یک رشته ۱۶ کاراکتری باینری است و کدگذاری هر خط قابل اجرا در فایل منبع را مطابق مشخصات ISA و زبان ماشین نشان می‌دهد. این برنامه مجموع ۱۰۰ عدد صحیح متوالی اول را محاسبه کرده و نتیجه محاسبه را در یک متغیر تعریف‌شده توسط کاربر به نام «sum» قرار می‌دهد. این برنامه از یک ساختار حلقه while استفاده می‌کند تا اعداد ۱ تا ۱۰۰ را پیمایش کرده و هر عدد را به متغیر «sum» اضافه کند. این برنامه تمامی قابلیت‌های «مستند شده» زبان اسمبلی کامپیوتر Hack را، به جز ورودی/خروجی نقشه‌برداری شده در حافظه، نشان می‌دهد. کد ماشین Hack تولید شده توسط اسمبلر در ستون آخر نشان داده شده و آدرس ROM مربوطه در ستون قبل از آن آمده است. توجه داشته باشید که توضیحات کامل خط، خطوط خالی و دستور تعریف برچسب هیچ کد ماشین تولید نمی‌کنند. همچنین، توضیحاتی که در پایان هر خط حاوی دستور اسمبلی قرار دارند، توسط اسمبلر نادیده گرفته می‌شوند. خروجی اسمبلر که در ستون آخر نشان داده شده است، یک رشته متنی متشکل از ۱۶ کاراکتر باینری است و نمایانگر عدد ۱۶ بیتی به صورت عدد صحیح باینری نیست. دستور A یک مقدار ثابت یا آدرس حافظه را مشخص می‌کند که در دستور C بعدی استفاده می‌شود. این مقدار در خط ۱۲ (D=D-A) برای محاسبه مقداری که در شرط شاخه حلقه استفاده می‌شود، به کار می‌رود. از آنجا که خط ۴ (@cnt) اولین ظاهر متغیر تعریف‌شده توسط کاربر «cnt» است، این دستور نماد را به اولین آدرس RAM بلااستفاده اختصاص می‌دهد. همچنین ثبات شبه M نیز به این آدرس اشاره می‌کند و RAM[16] به محل حافظه فعال RAM تبدیل می‌شود. در اینجا دستور، مقدار برچسب اختصاص یافته را که نمایانگر یک آدرس در حافظه ROM است، در ثبات A و ثبات شبه M بارگذاری می‌کند. دستور شاخه بدون شرط بعدی در خط ۲۲ (0;JMP) مقدار ثبات M را در ثبات شمارنده برنامه CPU بارگذاری می‌کند تا کنترل برنامه به ابتدای حلقه منتقل شود. کامپیوتر Hack هیچ دستور زبان ماشین مستقیمی برای متوقف کردن اجرای برنامه ارائه نمی‌دهد. | ## جمع‌بندی | دو خط پایانی برنامه (@END و 0;JMP) یک حلقه بی‌نهایت ایجاد می‌کنند که برنامه‌های اسمبلی Hack به طور قراردادی برای پایان دادن به برنامه‌های اجرا شده در شبیه‌ساز CPU از آن استفاده می‌کنند.