کامپیوترها چگونه اعداد را نمایش می‌دهند و دستورات را به باینری کدگذاری می‌کنند

زیر هر مقداری که یک برنامه دستکاری می‌کند و هر دستوری که یک پردازنده اجرا می‌کند، یک رشته بیت با عرض ثابت قرار دارد. این مقاله توضیح می‌دهد اعداد علامت‌دار و بدون علامت چگونه از یک الگوی باینری یکسان به شکل‌های متفاوتی تفسیر و نمایش داده می‌شوند، و خود دستورات ماشین چگونه در فیلدهای باینری ثابتی کدگذاری می‌شوند که سخت‌افزار می‌تواند با سرعت بالا آن‌ها را decode کند.

اعداد علامت‌دار و بدون علامتمکمل دوکدگذاری دستورات

~3 دقیقه مطالعه · آخرین به‌روزرسانی ۱۵ شهریور ۱۴۰۵

چرا اعداد به نمایش ثابت نیاز دارند

سخت‌افزار کامپیوتر هر مقدار را با تعداد ثابتی بیت ذخیره می‌کند، که معمولاً در گروه‌های ۳۲ بیتی یا ۶۴ بیتی به نام Words قرار می‌گیرند. چون تعداد بیت‌ها ثابت است، محدودیت سختی روی بازه مقادیر قابل‌نمایش وجود دارد، و همان الگوی بیتی می‌تواند بسته به نحوه تفسیرش معانی متفاوتی داشته باشد.

اعداد بدون علامت: نمایش فقط مقادیر غیرمنفی

یک Unsigned Number از تمام بیت‌های موجود برای نمایش مقدار استفاده می‌کند، بدون اینکه هیچ بیتی برای علامت رزرو شود. برای یک عدد بدون علامت n بیتی، بازه قابل‌نمایش این است:

بازه: 0 تا (2^n − 1)

نمایش بدون علامت معمولاً برای مقادیری استفاده می‌شود که منطقاً هرگز نمی‌توانند منفی باشند، مانند آدرس‌های حافظه.

اعداد علامت‌دار و مکمل دو

بیشتر محاسبات در برنامه‌های واقعی به مقادیر منفی نیز نیاز دارند. نمایشی که تقریباً به‌طور جهانی در سخت‌افزار امروزی استفاده می‌شود Two's Complement نام دارد.

در نمایش مکمل دو، بیت سمت چپ Sign Bit نامیده می‌شود: برای اعداد غیرمنفی صفر و برای اعداد منفی یک است، اما برخلاف نمایش ساده علامت-مقدار، بقیه بیت‌ها فقط یک مقدار ساده نیستند — کل الگو به‌گونه‌ای محاسبه می‌شود که جمع و تفریق با همان مدار سخت‌افزاری، صرف‌نظر از علامت، درست کار کند.

برای منفی کردن یک عدد در مکمل دو، تمام بیت‌ها معکوس شده و سپس ۱ به نتیجه اضافه می‌شود:

مرحله ۱: تمام بیت‌های عدد را معکوس کن
مرحله ۲: به نتیجه معکوس‌شده ۱ اضافه کن

این روش به‌طور خاص انتخاب شده چون اجازه می‌دهد همان مدار جمع‌کننده استفاده‌شده برای جمع بدون علامت، تفریق و اعداد منفی را نیز درست مدیریت کند، و نیاز به سخت‌افزار جداگانه را از بین می‌برد.

دستورات ماشین چگونه کدگذاری می‌شوند

درست همان‌طور که داده عددی به‌شکل الگوهای باینری با عرض ثابت ذخیره می‌شود، خود دستورات نیز به همین شکل کدگذاری می‌شوند. هر دستور RISC-V در یک کلمه ثابت ۳۲ بیتی بسته‌بندی می‌شود، که به Fields مجزا تقسیم شده، هرکدام حامل یک قطعه اطلاعات مشخص است.

یک فرمت دستور محاسباتی معمول شامل فیلدهایی مانند این‌هاست:

  • Opcode: مشخص می‌کند دستور به کدام دسته عملیات پایه تعلق دارد.
  • Destination Register (rd): مشخص می‌کند نتیجه کجا ذخیره خواهد شد.
  • Source Registers (rs1, rs2): مشخص می‌کنند مقادیر عملوند ورودی از کجا می‌آیند.
  • Funct Fields: بیت‌های اضافی مورد نیاز برای تمایز کامل عملیات دقیق را فراهم می‌کنند، وقتی opcode به‌تنهایی به‌اندازه کافی مشخص نیست.

این ساختار لایه‌ای فیلدها Format دستور نامیده می‌شود، و RISC-V تعداد کمی فرمت استاندارد تعریف می‌کند تا سخت‌افزار decode بتواند هر فیلد را با استفاده از همان موقعیت‌های بیتی ثابت در بسیاری از دستورات مختلف استخراج کند، و منطق decode را ساده و سریع نگه دارد.

چرا کدگذاری با عرض ثابت اهمیت دارد

ثابت نگه‌داشتن عرض هر دستور، با فیلدهایی که همیشه در موقعیت‌های بیتی قابل‌پیش‌بینی قرار دارند، به سخت‌افزار decode پردازنده اجازه می‌دهد عملوندها را استخراج کرده و عملیات را در یک گام واحد و ساده شناسایی کند، به‌جای نیاز به منطق تجزیه پیچیده و متغیر — که مستقیماً از اصل طراحی پیشین یعنی سریع نگه‌داشتن حالت رایج پشتیبانی می‌کند.

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

سخت‌افزار چگونه تقسیم انجام می‌دهد: خارج‌قسمت، باقیمانده و موارد خاص

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

ادامه

سخت‌افزار چگونه اعداد را ضرب می‌کند: از منطق ساده تا مدارهای واقعی

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

ادامه

سخت‌افزار چگونه جمع و تفریق انجام می‌دهد و سرریز را تشخیص می‌دهد

سخت‌افزار چگونه جمع و تفریق انجام می‌دهد و سرریز را تشخیص می‌دهد

ادامه

آرایه‌ها در مقابل اشاره‌گرها در سطح سخت‌افزار

در C، آرایه‌ها و اشاره‌گرها اغلب قابل‌تعویض به‌نظر می‌رسند، و بسیاری از برنامه‌نویسان با آن‌ها به‌عنوان یک چیز واحد رفتار می‌کنند. با این حال در سطح سخت‌افزار، آن‌ها به توالی‌های دستوری قابل‌توجهی متفاوت با ویژگی‌های کارایی متفاوت کامپایل می‌شوند. این مقاله این دو رویکرد را با استفاده از اسمبلی RISC-V مقایسه می‌کند تا دقیقاً نشان دهد چرا کد مبتنی بر اشاره‌گر اغلب سریع‌تر است.

ادامه

از کد منبع تا یک فرآیند در حال اجرا: ترجمه و یک مثال کامل مرتب‌سازی

تبدیل یک برنامه C به چیزی که سیستم‌عامل واقعاً بتواند اجرا کند شامل چندین مرحله ترجمه مجزاست، که هرکدام یک فایل میانی متفاوت تولید می‌کنند. این مقاله کل این خط لوله را از کامپایلر تا loader مرور می‌کند، سپس مفاهیم این فصل را روی یک مثال کامل و واقعی به‌کار می‌برد: ترجمه گام‌به‌گام یک روال مرتب‌سازی C به اسمبلی RISC-V.

ادامه

مدیریت آدرس‌های بزرگ و همگام‌سازی در RISC-V

یک دستور ۳۲ بیتی نمی‌تواند یک ثابت بزرگ یا یک آدرس حافظه دور را مستقیماً درون خودش جا دهد، و چند پردازنده‌ای که حافظه را به اشتراک می‌گذارند نمی‌توانند بدون هماهنگی، یک داده یکسان را با امنیت به‌روزرسانی کنند. این مقاله توضیح می‌دهد RISC-V چگونه مقادیر فوری و آدرس‌های بزرگ را از قطعات کوچک‌تر می‌سازد، و دستورات اتمیک چگونه اجازه می‌دهند برنامه‌های موازی با امنیت همگام شوند.

ادامه