هک کامپیوتر

## هک کامپیوتر
**هک کامپیوتر** یک طراحی نظری کامپیوتر است که توسط نوآم نیسان و شی‌مون شوکن ایجاد شده و در کتاب آن‌ها با عنوان *عناصر سیستم‌های محاسباتی: ساخت یک کامپیوتر مدرن از اصول اولیه* توضیح داده شده است. در استفاده از واژه «مدرن»، نویسندگان به یک ماشین دیجیتال و دودویی اشاره دارند که بر اساس مدل معماری فون نویمان طراحی شده است.

هک کامپیوتر برای ساخت مجازی عملی در یک برنامه شبیه‌ساز سخت‌افزار طراحی شده و بخشی از یک دوره پایه ولی جامع در سازماندهی و معماری کامپیوتر است. یکی از این دوره‌ها که توسط نویسندگان ایجاد شده و در دو بخش ارائه می‌شود، به‌صورت رایگان در قالب یک دوره آنلاین گسترده (MOOC) تحت عنوان *ساخت یک کامپیوتر مدرن از اصول اولیه: از NAND تا تتریس* در دسترس است. در دوازده پروژه این دوره، یادگیرندگان از یک گیت نند دو ورودی شروع کرده و در نهایت به یک کامپیوتر مجازی کاملاً عملیاتی می‌رسند، شامل سخت‌افزار (حافظه و CPU) و نرم‌افزار (اسمبلر، ماشین مجازی، زبان برنامه‌نویسی شبیه جاوا و سیستم عامل).

علاوه بر شبیه‌ساز سخت‌افزاری که برای پیاده‌سازی اولیه سخت‌افزار کامپیوتر استفاده می‌شود، یک برنامه شبیه‌ساز کامل هک کامپیوتر و اسمبلری که پروژه‌های توصیف‌شده در کتاب و دوره آنلاین را پشتیبانی می‌کند نیز در وب‌سایت نویسندگان در دسترس است.

## معماری سخت‌افزار

thumb|right|300px|دیاگرام بلوکی کلی کامپیوتر Hack: شامل CPU، ROM و RAM (Harvard architecture)

#### ساختار کلی
سخت‌افزار کامپیوتر Hack از سه عنصر پایه تشکیل شده است که در نمودار بلوکی نشان داده شده‌اند: دو واحد حافظه جداگانه ۱۶ بیتی و یک واحد پردازش مرکزی (CPU). از آنجا که داده‌ها توسط کامپیوتر به‌صورت کلمات ۱۶ بیتی منتقل و پردازش می‌شوند، کامپیوتر Hack به عنوان معماری ۱۶ بیتی طبقه‌بندی می‌شود. حافظه دستورالعمل‌ها، که از دید کامپیوتر به صورت حافظه فقط خواندنی (ROM) پیاده‌سازی شده است، کد برنامه باینری مونتاژ شده برای اجرا را نگه می‌دارد. حافظه دسترسی تصادفی (RAM) فضایی برای ذخیره داده‌های برنامه در حال اجرا فراهم می‌کند و خدمات و مناطق ذخیره‌سازی برای مکانیزم ورودی/خروجی نقشه‌برداری‌شده در حافظه کامپیوتر ارائه می‌دهد. پردازش داده‌ها و مدیریت کنترل برنامه توسط CPU انجام می‌شود. این سه واحد توسط باس‌های موازی به هم متصل شده‌اند. باس‌های آدرس (۱۵ بیتی) و همچنین باس‌های داده و دستورالعمل (۱۶ بیتی) برای واحدهای ROM و RAM کاملاً مستقل هستند. بنابراین، طراحی Hack از نظر ارتباط باس بین واحدهای حافظه و CPU، از مدل معماری هاروارد پیروی می‌کند. تمامی حافظه فقط به صورت آدرس‌دهی بر اساس کلمه قابل دسترسی است

## حافظه فقط‌خواندنی (ROM)
ماژول ROM کامپیوتر Hack به صورت یک آرایه خطی از ثبات‌های حافظه ۱۶ بیتی متوالی و قابل آدرس‌دهی جداگانه ارائه شده است. آدرس‌ها از ۰ (۰x۰۰۰۰) شروع می‌شوند. از آنجا که عناصر حافظه دستگاه‌های متوالی هستند، سیگنال ساعت سیستم توسط برنامه شبیه‌ساز و برنامه شبیه‌ساز کامپیوتر تأمین می‌شود. باس آدرس ROM عرض ۱۵ بیت دارد، بنابراین در مجموع ۳۲٬۷۶۸ کلمه جداگانه برای دستورالعمل‌های برنامه در دسترس است. آدرس کلمه فعال فعلی توسط ثبات شمارنده برنامه (Program Counter) در CPU تأمین می‌شود. مقدار موجود در ثبات حافظه ROM که توسط آدرس قرار داده‌شده روی باس آدرس دستورالعمل در یک سیکل ساعت مشخص شده، به عنوان دستورالعمل «فعلی» در ابتدای سیکل بعدی در دسترس قرار می‌گیرد. در این سیستم ثبات دستورالعمل وجود ندارد؛ دستورالعمل‌ها در هر سیکل از ثبات ROM فعال فعلی رمزگشایی می‌شوند.

## [[حافظه دسترسی تصادفی]] (RAM)
ماژول RAM نیز به صورت یک آرایه خطی متوالی از ثبات‌های حافظه ۱۶ بیتی خواندنی-نوشتنی و قابل آدرس‌دهی جداگانه پیاده‌سازی شده است، اما از نظر عملکردی به سه بخش تقسیم شده است: آدرس‌های ۰ (۰x۰۰۰۰) تا ۱۶۳۸۳ (۰x۳FFF): شامل ثبات‌های ۱۶ بیتی خواندنی-نوشتنی مرسوم هستند و برای ذخیره داده‌های عمومی برنامه طراحی شده‌اند. آدرس‌های ۱۶۳۸۴ (۰x۴۰۰۰) تا ۲۴۵۷۵ (۰x۵FFF): مشابه RAM داده هستند اما برای استفاده توسط زیرسیستم ورودی/خروجی صفحه‌نمایش داخلی اختصاص داده شده‌اند. داده‌های نوشته شده به این محدوده باعث ایجاد خروجی روی صفحه‌نمایش مجازی ۲۵۶×۵۱۲ می‌شوند. در صورت عدم نیاز برنامه به خروجی صفحه، می‌توان از این ثبات‌ها برای ذخیره داده‌های عمومی استفاده کرد. آدرس ۲۴۵۷۶ (۰x۶۰۰۰): شامل یک ثبات یک‌کلمه‌ای است که مقدار فعلی آن توسط خروجی کیبورد متصل به کامپیوتری که برنامه شبیه‌ساز Hack را اجرا می‌کند، کنترل می‌شود. این ثبات به عنوان نقشه حافظه کیبورد فقط‌خواندنی تعریف شده است. آدرس‌های حافظه داده در بازه ۲۴۵۷۷ (۰x۶۰۰۱) تا ۳۲۷۶۷ (۰x۷FFF) نامعتبر هستند. تغییر وضعیت ثبات RAM انتخاب‌شده توسط سیگنال ساعت سیستم هماهنگ می‌شود.

## [[واحد پردازش مرکزی]] (CPU)

thumb|right|400px|دیاگرام داخلی CPU کامپیوتر Hack: شامل ALU، رجیسترهای A، D، PC و کنترل‌ها
واحد پردازش مرکزی (CPU) کامپیوتر Hack یک واحد منطقی یکپارچه با ساختار داخلی است و بسیاری از عملکردهای CPUهای ساده و تجاری را ارائه می‌دهد. پیچیده‌ترین عنصر CPU، واحد حسابی-منطقی (ALU) است که محاسبات کامپیوتر را انجام می‌دهد. ALU یک دستگاه منطق ترکیبی است که دو ورودی ۱۶ بیتی و یک خروجی ۱۶ بیتی دارد. محاسبات تولید شده به عنوان خروجی از ورودی‌ها توسط مجموعه‌ای از شش ورودی تک‌بیتی ترتیب‌دار مشخص می‌شوند. همچنین ALU دو پرچم وضعیت تک‌بیتی ارائه می‌دهد که نشان می‌دهند آیا نتیجه محاسبه صفر است (پرچم zr) یا منفی (پرچم ng). CPU همچنین شامل دو ثبات ۱۶ بیتی به نام‌های D و A است: ثبات D (Data): ثبات عمومی که مقدار فعلی آن همیشه به عنوان ورودی x به ALU ارسال می‌شود. در برخی دستورالعمل‌ها مقدار آن نادیده گرفته می‌شود. ثبات A (Address): می‌تواند مقدار فعلی خود را به عنوان ورودی y به ALU ارائه دهد و همچنین برای آدرس‌دهی حافظه داده و به عنوان آدرس هدف دستورهای شاخه‌ای در حافظه دستورالعمل استفاده شود. برای این منظور، ثبات A به یک «ثبات شبه» به نام M مرتبط است که به‌طور مستقیم پیاده‌سازی نشده است و نمایانگر مقداری است که در RAM و در آدرسی که مقدار فعلی A مشخص می‌کند، نگهداری می‌شود. آخرین عنصر مهم در CPU، ثبات شمارنده برنامه (PC) است. PC یک شمارنده باینری ۱۶ بیتی است که ۱۵ بیت پایین آن آدرس دستورالعمل بعدی در حافظه دستورالعمل را مشخص می‌کند. مگر اینکه دستور شاخه‌ای مشخص شود، PC در پایان هر سیکل ساعت افزایش می‌یابد. CPU همچنین شامل منطق تغییر ترتیب اجرای دستورالعمل‌ها تحت کنترل برنامه است تا PC به مقدار غیرمتوالی تنظیم شود. PC دارای یک ورودی تک‌بیتی ریست است که مقدار آن را به ۰ (۰x۰۰۰۰) تنظیم می‌کند. برخلاف بسیاری از طراحی‌های واقعی CPU، هیچ مکانیزم سخت‌افزاری قابل دسترسی برنامه برای وقفه‌های داخلی یا خارجی و پشتیبانی از فراخوانی توابع ارائه نشده است.

## ورودی و خروجی خارجی (I/O)
کامپیوتر Hack از روش نقشه‌برداری حافظه برای ورودی/خروجی استفاده می‌کند. خروجی سیاه و سفید بیت‌مپ شده به صفحه‌نمایش مجازی 256×512 با نوشتن یک بیت‌مپ از خروجی موردنظر در مکان‌های حافظه داده از 16384 (0x4000) تا 24575 (0x5FFF) انجام می‌شود. کلمات داده در این بازه آدرس به عنوان یک آرایه خطی از بیت‌ها در نظر گرفته می‌شوند که هر بیت نمایانگر وضعیت سیاه/سفید یک پیکسل بر روی صفحه‌نمایش مجازی شبیه‌ساز کامپیوتر است.

کم‌ارزش‌ترین بیت کلمه در اولین آدرس حافظه بخش RAM صفحه، پیکسل در گوشه بالای سمت چپ صفحه را سفید می‌کند اگر مقدار آن 0 باشد و سیاه اگر 1 باشد. بیت بعدی با ارزش بیشتر در همان کلمه، پیکسل بعدی به سمت راست را کنترل می‌کند و به همین ترتیب ادامه می‌یابد. پس از آن که اولین ردیف 512 پیکسلی توسط 32 کلمه اول حافظه صفحه توصیف شد، نگاشت به همین صورت برای ردیف دوم با 32 کلمه بعدی ادامه می‌یابد. منطق خارجی کامپیوتر، بخش حافظه RAM صفحه را می‌خواند و صفحه مجازی را به‌روزرسانی می‌کند.

اگر یک صفحه‌کلید به کامپیوتری که برنامه شبیه‌ساز CPU را اجرا می‌کند متصل باشد، شبیه‌ساز یک کد اسکن 16 بیتی مربوط به کلیدی که در حین اجرای برنامه فشرده شده است را در ثبات صفحه‌کلید در آدرس RAM 24576 (0x6000) قرار می‌دهد. اگر هیچ کلیدی فشرده نشده باشد، این ثبات مقدار 0 را نگه می‌دارد. شبیه‌ساز یک دکمه تغییر حالت برای فعال/غیرفعال کردن صفحه‌کلید ارائه می‌دهد.

طرح کدگذاری به‌طور نزدیک از کدگذاری ASCII برای کاراکترهای قابل چاپ پیروی می‌کند و اثر کلید Shift معمولاً رعایت می‌شود. کدهایی نیز برای سایر کلیدهای معمول در صفحه‌کلید استاندارد ارائه شده است؛ برای مثال کلیدهای کنترل جهت (←، ↑، ↓، →) و کلیدهای Fn.

## چرخه عملیاتی
عملیات مرحله‌به‌مرحله CPU و واحدهای حافظه توسط یک ساعت سیستم (Clock) کنترل می‌شود که در هر دو برنامه شبیه‌ساز سخت‌افزار و شبیه‌ساز کامپیوتر تعبیه شده است. در ابتدای یک سیکل ساعت، دستورالعمل موجود در آدرس ROM که توسط مقدار فعلی شمارنده برنامه (PC) مشخص شده، رمزگشایی می‌شود.

ورودی‌های ALU که توسط دستورالعمل مشخص شده‌اند، در صورت نیاز آماده می‌شوند. محاسبات تعیین‌شده توسط ALU انجام شده و پرچم‌های وضعیت مربوطه تنظیم می‌شوند. نتیجه محاسبه طبق دستورالعمل ذخیره می‌شود. در نهایت، شمارنده برنامه به مقدار دستورالعمل بعدی مورد نیاز به‌روزرسانی می‌شود. اگر دستورالعمل فعلی شاخه‌ای (Branch) مشخص نکرده باشد، مقدار PC به سادگی افزایش می‌یابد. اگر شاخه‌ای مشخص شده باشد، PC از مقدار ثبات A بارگذاری می‌شود و آدرس دستورالعمل بعدی برای اجرا در آن قرار می‌گیرد. سپس چرخه با استفاده از مقدار فعلی PC تکرار می‌شود.

به دلیل استفاده از مدل معماری حافظه هاروارد، کامپیوتر Hack طوری طراحی شده است که دستورالعمل فعلی را اجرا کرده و دستور بعدی را در یک سیکل ساعت دو قسمتی «دریافت» کند. سرعت ساعت می‌تواند توسط یک عنصر کنترل در هر دو شبیه‌ساز سخت‌افزار و شبیه‌ساز CPU تغییر یابد. با این حال، مستقل از سرعت انتخاب‌شده، هر دستورالعمل به طور کامل در یک سیکل اجرا می‌شود. کاربر همچنین می‌تواند برنامه را مرحله‌به‌مرحله (Single-step) اجرا کند.

اجرای برنامه‌ای که در ROM بارگذاری شده است، توسط بیت ریست (Reset) CPU کنترل می‌شود. اگر مقدار بیت ریست 0 باشد، اجرا طبق چرخه عملیاتی توضیح داده شده ادامه می‌یابد. تنظیم بیت ریست به 1، مقدار PC را به 0 (0x0000) می‌برد. سپس با بازگرداندن مقدار بیت ریست به 0، اجرای برنامه فعلی از اولین دستور آغاز می‌شود؛ با این حال، حافظه RAM مقادیر باقی‌مانده از فعالیت‌های قبلی قبل از ریست را حفظ می‌کند.

هیچ پشتیبانی سخت‌افزاری یا زبان ماشین برای وقفه‌ها (Interrupt) وجود ندارد.

## نوع داده‌ها
مقادیر ذخیره‌شده در حافظه ROM باید دستورالعمل‌های معتبر زبان ماشین Hack را نمایندگی کنند، همان‌طور که در بخش معماری مجموعه دستورالعمل‌ها (ISA) و زبان ماشین توضیح داده شده است.

هر مقدار ۱۶ بیتی می‌تواند در RAM ذخیره شود. نوع داده مقدار ذخیره‌شده در RAM از مکان آن و/یا کاربردش در برنامه استنتاج می‌شود. نوع داده اصلی پشتیبانی شده توسط سخت‌افزار، عدد صحیح ۱۶ بیتی با علامت است که به صورت مکمل دو (۲’s complement) نمایش داده می‌شود. بنابراین، اعداد صحیح علامت‌دار دارای محدوده −۳۲۷۶۸ تا ۳۲۷۶۷ هستند.

۱۵ بیت پایین یک مقدار در RAM همچنین می‌تواند به عنوان یک آدرس در ROM یا RAM در حس یک اشاره‌گر (Pointer) در نظر گرفته شود.

برای مقادیری که در ثبات‌های حافظه RAM اختصاص داده‌شده برای ورودی/خروجی صفحه‌نمایش ذخیره می‌شوند، اگر صفحه روشن باشد، مقدار به عنوان نقشه ۱۶ پیکسلی از صفحه مجازی ۲۵۶ ردیف × ۵۱۲ ستون توسط زیرسیستم I/O مستقل کامپیوتر تفسیر می‌شود.

مقدار کد ذخیره‌شده در حافظه صفحه‌کلید می‌تواند برنامه‌نویسی شده خوانده شود و برای استفاده در برنامه تفسیر گردد.

هیچ پشتیبانی سخت‌افزاری برای نوع داده نقطه شناور (Floating-point) وجود ندارد.

## معماری مجموعه دستورالعمل‌ها (ISA) و زبان ماشین
مجموعه دستورالعمل‌ها (ISA) و زبان ماشین مشتق شده از آن در کامپیوتر Hack نسبت به بسیاری از معماری‌های دیگر محدود است. اگرچه ۶ بیت استفاده شده برای مشخص کردن محاسبات توسط ALU می‌تواند ۶۴ دستور متفاوت را مشخص کند، تنها ۱۸ دستور به‌طور رسمی در ISA کامپیوتر Hack پیاده‌سازی شده‌اند. از آنجا که سخت‌افزار Hack از ضرب و تقسیم اعداد صحیح یا فراخوانی توابع پشتیبانی مستقیم ندارد، هیچ دستور زبان ماشین معادل برای این عملیات‌ها در ISA وجود ندارد. زبان ماشین Hack فقط دارای دو نوع دستور است که هر کدام در ۱۶ بیت باینری کدگذاری می‌شوند

## دستورهای A (A-instructions)
دستورهایی که بیت باارزش‌ترین آن‌ها برابر با "0" است، به عنوان **دستورهای A** یا **دستورهای آدرس** شناخته می‌شوند. دستور A به صورت بیت‌فیلد به شکل زیر کدگذاری می‌شود:

0b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 b10 b11 b12 b13 b14 

•	0 – بیت باارزش‌ترین دستور A همیشه "0" است.

•	b14–b0 – این ۱۵ بیت نمایانگر نمایش باینری یک عدد صحیح غیرمنفی در بازه ۰ تا ۳۲۷۶۷ هستند.

هنگامی که این دستور اجرا می‌شود، ۱۵ بیت باقی‌مانده به صورت left-zero extended در ثبات A پردازنده بارگذاری می‌شوند. به طور همزمان، ثبات RAM که آدرس آن توسط مقدار دستور مشخص شده است، برای عملیات خواندن یا نوشتن در چرخه کلاک بعدی فعال می‌شود

## دستورالعمل‌های C (C-instructions)

نوع دیگر دستور، **دستورالعمل‌های C** یا **دستورالعمل‌های محاسباتی** است که بخش اصلی برنامه‌نویسی را انجام می‌دهد.

بیت باارزش‌ترین این دستور برابر با "۱" است و ۱۵ بیت باقی‌مانده به صورت بیت‌فیلد کدگذاری شده‌اند تا ورودی‌ها، محاسبه انجام شده و محل ذخیره خروجی مشخص شوند.

این دستور می‌تواند بر اساس نتیجه محاسبه اخیر، عملیات شاخه‌ای (Branch) را نیز مشخص کند.

فرمت دستور به صورت زیر است:

C-instruction: dest=comp;jump

ممکن است یکی از بخش‌های **dest** یا **jump** خالی باشد؛ به این ترتیب دو حالت ممکن است: dest=comp یا comp;jump.

دستور C به صورت بیت‌فیلد کدگذاری می‌شود:

111a c1 c2 c3 c4 c5 c6  d1 d2 d3 j1 j2 j3

1 – بیت باارزش‌ترین دستور C همیشه "1" است.

11 – دو بیت بعدی توسط CPU نادیده گرفته می‌شوند و طبق قرارداد همیشه "1" هستند.

a – این بیت منبع ورودی y به ALU را مشخص می‌کند.

c1–c6 – شش بیت کنترل که نوع محاسبه و ورودی‌های ALU را تعیین می‌کنند.

d1–d3 – سه بیت که مقصد ذخیره خروجی ALU را مشخص می‌کنند.

j1–j3 – سه بیت که شرط شاخه‌ای، شاخه بدون شرط یا عدم شاخه را مشخص می‌کنند.

در این جدول‌ها:

A نمایانگر مقدار فعلی ثبات A است.

D نمایانگر مقدار فعلی ثبات D است.

M نمایانگر مقدار موجود در RAM در آدرسی است که در ثبات A قرار دارد (M == RAM[A])

### کدهای محاسبات ALU و نمادهای اسمبلی

### کدهای مقصد ذخیره خروجی ALU

### کدهای شاخه (Jump)

## زبان اسمبلی
کامپیوتر Hack دارای یک زبان اسمبلی متنی است که برای نوشتن برنامه‌ها روی پلتفرم سخت‌افزاری این کامپیوتر طراحی شده و ISA کامپیوتر Hack را پیاده‌سازی می‌کند.
برنامه‌های زبان اسمبلی Hack می‌توانند در فایل‌های متنی با پسوند .asm ذخیره شوند. فایل‌های منبع زبان اسمبلی Hack به حروف بزرگ و کوچک حساس هستند. هر خط متن می‌تواند شامل یکی از عناصر زیر باشد:
•	خط خالی
•	توضیح (Comment)
•	اعلام برچسب (Label) همراه با توضیح اختیاری در پایان خط
•	دستور A (A-instruction) همراه با توضیح اختیاری در پایان خط
•	دستور C (C-instruction) همراه با توضیح اختیاری در پایان خط
هر یک از این انواع خط‌ها دارای نحو (Syntax) خاصی هستند و ممکن است شامل نمادهای از پیش تعریف شده، نمادهای تعریف‌شده توسط کاربر یا مقادیر عددی باشند. خطوط خالی و توضیحات توسط اسمبلر نادیده گرفته می‌شوند. اعلام برچسب‌ها، دستورهای A و C نباید شامل فاصله داخلی باشند، اگرچه فاصله در ابتدا یا انتهای خط مجاز است و نادیده گرفته می‌شود.

توضیحات (Comments)
هر متنی که با دو کاراکتر // شروع شود، به عنوان توضیح در نظر گرفته می‌شود. توضیحات می‌توانند در یک خط جداگانه قرار گیرند یا در پایان هر خط برنامه باشند. تمام متن بعد از نماد // تا انتهای خط توسط اسمبلر نادیده گرفته می‌شود و هیچ کد ماشینی تولید نمی‌کند.

## نمادها و مقادیر عددی
زبان اسمبلی Hack امکان استفاده از نمادهای الفبایی-عددی (Alphanumeric) برای اهداف مختلف را فراهم می‌کند.
یک نماد می‌تواند شامل حروف الفبا (بزرگ و کوچک) یا ارقام باشد و می‌تواند شامل _، .، $ و : نیز باشد. نمادها نباید با یک رقم شروع شوند و حساس به حروف بزرگ و کوچک هستند. نمادهای تعریف‌شده توسط کاربر برای ایجاد نام متغیرها و برچسب‌ها استفاده می‌شوند.
اسمبلر زبان اسمبلی Hack برخی نمادهای از پیش تعریف شده را نیز می‌شناسد:
•	نمادهای R0 تا R15 به ترتیب به اعداد ۰ تا ۱۵ اختصاص دارند و نمایانگر ثبات‌های عمومی هستند؛ بنابراین این نمادها آدرس‌های حافظه داده ۰ تا ۱۵ را مشخص می‌کنند.
•	نمادهای از پیش تعریف شده دیگر شامل SCREEN و KBD هستند که آدرس شروع صفحه نمایش مجازی (16384) و ورودی صفحه‌کلید (24576) را مشخص می‌کنند.
•	همچنین نمادهایی مانند SP، LCL، ARG، THIS و THAT برای ساختن پشته نرم‌افزار سیستم عامل استفاده می‌شوند.
یک رشته از ارقام ده‌دهی (۰–۹) می‌تواند برای نمایش یک مقدار غیرمنفی در بازه ۰ تا ۳۲۷۶۷ استفاده شود. استفاده از علامت منفی برای اعداد مجاز نیست و نمایش باینری یا هشت‌تایی پشتیبانی نمی‌شود.
## متغیرها (Variables)
نمادهای تعریف‌شده توسط کاربر می‌توانند به عنوان متغیر در برنامه اسمبلی ایجاد شوند؛ یعنی یک ثبات RAM با نام مشخص. هنگام اسمبل شدن برنامه، این نمادها به یک آدرس RAM اختصاص می‌یابند. بنابراین، متغیرها هنگام ظاهر شدن در برنامه باید به عنوان آدرس حافظه در نظر گرفته شوند.
متغیرها به‌طور ضمنی زمانی تعریف می‌شوند که اولین بار در یک دستور A ظاهر شوند. در هنگام پردازش توسط اسمبلر، نماد متغیر به یک مقدار صحیح مثبت و یکتا اختصاص داده می‌شود که از آدرس ۱۶ شروع می‌شود. آدرس‌ها به ترتیب ظاهر شدن متغیرها در کد منبع تخصیص داده می‌شوند. به طور قراردادی، نمادهای تعریف‌شده توسط کاربر که متغیرهای برنامه را مشخص می‌کنند، با حروف کوچک نوشته می‌شوند.

## برچسب‌ها (Labels)
برچسب‌ها نمادهایی هستند که با پرانتز باز و بسته ( ) مشخص می‌شوند. آن‌ها در یک خط جداگانه تعریف شده و توسط اسمبلر به آدرس حافظه دستورالعمل خط بعدی اختصاص داده می‌شوند. برچسب‌ها تنها یک بار می‌توانند تعریف شوند، اما می‌توانند چندین بار در برنامه استفاده شوند، حتی قبل از خطی که در آن تعریف شده‌اند.
برچسب‌ها به طور قراردادی با حروف بزرگ نوشته می‌شوند و برای مشخص کردن آدرس هدف دستورهای شاخه‌ای C استفاده می‌شوند.

## دستورهای A (A-instructions)
دستور A دارای نحو زیر است:
@xxxx
که xxxx می‌تواند یک مقدار عددی در بازه ۰ تا ۳۲۷۶۷، یک برچسب یا یک متغیر (از پیش تعریف شده یا تعریف شده توسط کاربر) باشد. هنگام اجرا، این دستور مقدار ۱۵ بیتی نمایانگر xxxx را در ثبات A و ثبات شبه M بارگذاری می‌کند. مقدار ۱۵ بیتی در ثبات A به ۱۶ بیت با افزودن صفر در سمت چپ تبدیل می‌شود.
کاربردهای دستور A
1.	تنها راه برای وارد کردن مقدار عددی غیرمنفی به کامپیوتر تحت کنترل برنامه؛ یعنی برای ایجاد ثوابت برنامه استفاده می‌شود.
2.	مشخص کردن مکان حافظه RAM با استفاده از مکانیزم ثبات شبه M برای استفاده بعدی توسط دستور C.
3.	تعیین آدرس هدف شاخه‌ای در دستور C با استفاده از مقدار فعلی ثبات A، معمولاً با ارجاع به یک برچسب، قبل از دستور شاخه‌ای.

## دستورهای C (C-Instructions)
دستورهای C، موتور محاسباتی ALU و قابلیت‌های کنترل جریان برنامه در کامپیوتر Hack را هدایت می‌کنند. نحو دستور توسط سه فیلد تعریف می‌شود: comp، dest و jump. فیلد comp در هر دستور C ضروری است.
نحو دستور C به شکل زیر است:
dest=comp;jump
•	کاراکترهای = و ; برای جداسازی فیلدها استفاده می‌شوند. اگر فیلد dest استفاده نشود، کاراکتر = حذف می‌شود. اگر فیلد jump استفاده نشود، کاراکتر ; حذف می‌شود.
•	دستور C هیچ فاصله داخلی مجازی ندارد.
•	فیلد comp باید یکی از ۲۸ کد Mnemonic مستند شده باشد و با حروف بزرگ و بدون فاصله نوشته شود.
•	فیلد dest می‌تواند برای مشخص کردن یک یا چند مکان ذخیره نتیجه محاسبه استفاده شود. اگر حذف شود، مقدار محاسبه شده ذخیره نمی‌شود.
•	فیلد jump می‌تواند آدرس ROM دستور بعدی را مشخص کند. اگر حذف شود، اجرا با دستور بعدی ادامه می‌یابد.

## اسمبلر (Assembler)
نرم‌افزارهای رایگان پشتیبانی‌کننده از کامپیوتر Hack شامل برنامه خط فرمان اسمبلر هستند. اسمبلر فایل‌های منبع زبان اسمبلی Hack (*.asm) را می‌خواند و فایل‌های خروجی زبان ماشین Hack (*.hack) تولید می‌کند.
•	فایل خروجی یک فایل متنی است که هر خط آن یک رشته ۱۶ کاراکتری باینری است و کدگذاری هر خط قابل اجرا در فایل منبع را مطابق مشخصات ISA و زبان ماشین نشان می‌دهد.
•	فایل تولید شده می‌تواند توسط شبیه‌ساز Hack بارگذاری شود.

## مثال برنامه زبان اسمبلی

در ادامه یک برنامه نمونه حاشیه‌دار شده (annotated) به زبان اسمبلی Hack آورده شده است. این برنامه مجموع ۱۰۰ عدد صحیح متوالی اول را محاسبه کرده و نتیجه محاسبه را در یک متغیر تعریف‌شده توسط کاربر به نام «sum» قرار می‌دهد. این برنامه از یک ساختار حلقه while استفاده می‌کند تا اعداد ۱ تا ۱۰۰ را پیمایش کرده و هر عدد را به متغیر «sum» اضافه کند. متغیر تعریف‌شده توسط کاربر «cnt» مقدار فعلی عدد در طول حلقه را نگه می‌دارد. این برنامه تمامی قابلیت‌های «مستند شده» زبان اسمبلی کامپیوتر Hack را، به جز ورودی/خروجی نقشه‌برداری شده در حافظه، نشان می‌دهد. این برنامه ترجمه اسمبلی Hack قطعه کد زیر به زبان C است


```c
// جمع اعداد از 1 تا 100 
 int cnt = 1; 
 int sum = 0; 
while (cnt <= 100) {
 sum += cnt; cnt++;
 }
```


این برنامه شامل یک حلقه `while` است که اعداد ۱ تا ۱۰۰ را طی کرده و هر عدد را محتوای فایل منبع زبان اسمبلی Hack در ستون دوم با فونت بولد نشان داده شده است. شماره خطوط برای مرجع در توضیحات ارائه شده‌اند اما در کد منبع واقعی وجود ندارند. کد ماشین Hack تولید شده توسط اسمبلر در ستون آخر نشان داده شده و آدرس ROM مربوطه در ستون قبل از آن آمده است. توجه داشته باشید که توضیحات کامل خط، خطوط خالی و دستور تعریف برچسب هیچ کد ماشین تولید نمی‌کنند. همچنین، توضیحاتی که در پایان هر خط حاوی دستور اسمبلی قرار دارند، توسط اسمبلر نادیده گرفته می‌شوند.

خروجی اسمبلر که در ستون آخر نشان داده شده است، یک رشته متنی متشکل از ۱۶ کاراکتر باینری است و نمایانگر عدد ۱۶ بیتی به صورت عدد صحیح باینری نیست.

توجه داشته باشید که توالی دستورات معمولاً الگوی «دستور A، دستور C، دستور A، دستور C، …» را دنبال می‌کند. این الگو برای برنامه‌های زبان اسمبلی Hack رایج است. دستور A یک مقدار ثابت یا آدرس حافظه را مشخص می‌کند که در دستور C بعدی استفاده می‌شود.

هر سه نوع استفاده از دستور A در این برنامه نمایش داده شده است. در خط ۱۱ (@100)، مقدار ثابت ۱۰۰ در ثبات A بارگذاری می‌شود. این مقدار در خط ۱۲ (D=D-A) برای محاسبه مقداری که در شرط شاخه حلقه استفاده می‌شود، به کار می‌رود.

از آنجا که خط ۴ (@cnt) اولین ظاهر متغیر تعریف‌شده توسط کاربر «cnt» است، این دستور نماد را به اولین آدرس RAM بلااستفاده اختصاص می‌دهد. در این نمونه، آدرس ۱۶ است و این مقدار در ثبات A بارگذاری می‌شود. همچنین ثبات شبه M نیز به این آدرس اشاره می‌کند و RAM[16] به محل حافظه فعال RAM تبدیل می‌شود.

سومین استفاده از دستور A در خط ۲۱ (@LOOP) دیده می‌شود. در اینجا دستور، مقدار برچسب اختصاص یافته را که نمایانگر یک آدرس در حافظه ROM است، در ثبات A و ثبات شبه M بارگذاری می‌کند. دستور شاخه بدون شرط بعدی در خط ۲۲ (0;JMP) مقدار ثبات M را در ثبات شمارنده برنامه CPU بارگذاری می‌کند تا کنترل برنامه به ابتدای حلقه منتقل شود.

کامپیوتر Hack هیچ دستور زبان ماشین مستقیمی برای متوقف کردن اجرای برنامه ارائه نمی‌دهد. دو خط پایانی برنامه (@END و 0;JMP) یک حلقه بی‌نهایت ایجاد می‌کنند که برنامه‌های اسمبلی Hack به طور قراردادی برای پایان دادن به برنامه‌های اجرا شده در شبیه‌ساز CPU از آن استفاده می‌کنند.

## مطالعه بیشتر

Hennessy, John L., & Patterson, David A. (2019). *Computer Architecture: A Quantitative Approach*, 6th Edition. Cambridge, Massachusetts: Morgan Kaufmann Publishers.

Justice, Matthew. (2021). *How Computers Really Work*. San Francisco, California: No Starch Press.

Malvino, Albert P., & Brown, Jerald A. (1993). *Digital Computer Electronics*, 3rd Edition. New York, New York: Glencoe McGraw-Hill.

Null, Linda, & Lobur, Julia. (2019). *The Essentials of Computer Organization and Architecture*, 5th Edition. Burlington, Massachusetts: Jones and Bartlett Learning.

Patt, Yale N., & Patel, Sanjay J. (2020). *Introduction to Computing Systems: From Bits and Gates to C and Beyond*, 3rd Edition. New York, New York: McGraw Hill Education.

Petzold, Charles. (2009). *Code: The Hidden Language of Computer Hardware and Software*. Redmond, Washington: Microsoft Press.

Scott, John Clark. (2009). *But How Do It Know? The Basic Principles of Computers for Everyone*. Oldsmar, Florida: John C. Scott.

Whipple, Richard. (2019). *Build Your Own Computer from Scratch*. Seattle, Washington: Amazon Kindle.

## منابع
1.    *Nisan, Noam; Schocken, Shimon (2021). The Elements of Computing Systems: Building a Modern Computer from First Principles, 2nd Edition. Cambridge, Massachusetts: The MIT Press.*

2.     Schocken, Shimon (2021), Nand to Tetris Syllabus.

3.     *"Build a Modern Computer from First Principals: From Nand to Tetris". Retrieved 21 August 2021.*

4.     *"From Nand to Tetris". Retrieved 23 August 2021.*

## پیوند بین زبانی
 :en:Hack_computer.