مجموعه دستورالعمل

در علوم رایانه، یک معماری مجموعهٔ دستورالعمل (instruction set architecture (ISA))، نوعی مدل انتزاعی از یک رایانه است که به آن معماری یا معماری رایانه نیز می‌گویند. نمود یک آی اس ای، مثلاً یک واحد پردازش مرکزی، پیاده‌سازی(implementation) نام دارد.
به‌طور کلی یک آی اس ای، بیانگر انواع دادهٔ مورد پشتیبانی، رجیسترها، پشتیبانی سخت‌افزاری برای مدیریت حافظه اصلی، ویژگی‌های اساسی (همچون پایداری حافظه، حالت‌های آدرس دهی، حافظهٔ مجازی) و مدل ورودی/خروجی خانواده ای از پیاده‌سازی‌های آی اس ای مورد نظر است.
یک آی اس ای، رفتار کد ماشین را که روی پیاده‌سازی‌های آن آی اس ای اجرا می‌شود، مشخص می‌کند، به گونه‌ای که وابستگی به مشخصات آن پیاده‌سازی نداشته باشد و بدین طریق موجب سازگاری باینری (binary compatibility) بین پیاده‌سازی‌ها می‌شود. این امر امکان پیاده‌سازی‌های متعدد از یک آی اس ای که از لحاظ عملکرد، اندازه فیزیکی، و قیمت تفاوت دارند، ولی می‌توانند کد ماشین یکسانی را اجرا کنند فراهم می‌آورد، به گونه ای که می‌توان یک ماشین با عملکرد پایین و قیمت پایین را، با یک ماشین با قیمت بالاتر و عملکرد بالاتر، بدون نیاز به تعویض نرم‌افزار جایگزین کرد. همچنین، این قابلیت باعث تکامل ریز معماری‌های پیاده‌سازی‌های این آی اس ای می‌شود، به نحوی که، یک پیاده‌سازی جدیدتر با کارایی بالاتر از یک آی اس ای، بتواند نرم‌افزاری را اجرا کند که روی نسل‌های پیشین پیاده‌سازی کار می‌کند.
اگر یک سیستم عامل، یک رابط باینری اپلیکیشن(application binary interface) استاندارد و سازگار را برای یک آی اس ای خاص حفظ کند، آنگاه کد ماشین برای آن آی اس ای و سیستم عامل، روی پیاده‌سازی‌های بعدی آن در آینده و نسخه‌های جدیدتر آن سیستم عامل اجرا خواهد شد. با این وجود، اگر یک آی اس ای، اجرای چندین سیستم عامل را پشتیبانی کند، این تضمین وجود ندارد که کد ماشین برای یک سیستم عامل، روی سیستم عامل دیگر اجرا شود، مگر اینکه سیستم عامل اول از اجرای کد ماشین ساخته شده برای سیستم عامل دیگر پشتیبانی کند.
یک آی اس ای را می‌توان با اضافه کردن دستورالعمل‌ها یا سایر قابلیت‌ها یا اضافه کردن پشتیبانی برای آدرس‌ها و مقادیر دادهٔ بزرگتر، بسط داد. در این حالت یک پیاده‌سازی از آی اس ای‌های بسط یافته را کماکان می‌توان برای اجرای کد ماشین برای نسخه‌هایی از همان آی اس ای بدون بسط‌های ذکر شده، استفاده کرد. کدهای ماشینی که از این بسط‌ها استفاده می‌کنند، فقط روی پیاده‌سازی‌هایی اجرا می‌شوند که از این بسط‌ها پشتیبانی کنند.
این قابلیت‌های فراهم کردن سازگاری باینری، باعث شده‌است که آی اس ای‌ها، یکی از اساسی‌ترین فرم‌های انتزاعی در رایانش باشند.

مرور

معماری مجموعه دستورالعمل را باید از ریز معماری(microarchitecture) افتراق داد. ریز معماری، مجموعه ای از تکنیک‌های طراحی پردازنده است که در یک پردازنده خاص برای پیاده‌سازی مجموعهٔ دستورالعمل استفاده می‌شود. پردازنده‌هایی با ریز معماری‌های متفاوت می‌توانند یک مجموعه دستورالعمل مشترک داشته باشند. برای مثال، اینتل پنتیوم و Advanced Micro Devices Athlon تقریباً نسخه‌های مشابهی از مجموعه دستورالعمل x86 را پیاده‌سازی می‌کنند، اما دارای طراحی داخلی کاملاً متفاوتی هستند.

طبقه‌بندی آی اس ای

یک آی اس ای را می‌توان به شیوه‌های مختلفی طبقه‌بندی کرد. یک روش طبقه‌بندی معمول بر مبنای پیچیدگی معماری است. یک رایانه با مجموعه دستورالعمل پیچیده (complex instruction set computer) دارای دستورالعمل‌های اختصاصی بسیاری است، که برخی از آن‌ها ممکن است به ندرت در برنامه‌های عملی استفاده شوند. یک رایانه با مجموعه دستورالعمل کاهش یافته (reduced instruction set computer)، با پیاده‌سازی کارامد صرف دستورالعمل‌هایی که به‌طور مکرر در برنامه‌ها استفاده می‌شوند، پردازنده را ساده می‌کند، در عین حال، عملیات کمتر رایج، از طریق ساب روتین‌ها پیاده‌سازی می‌شوند، که در نتیجه، افزایش زمان اجرای پردازنده، با استفاده خیلی کم از این عملیات جبران می‌شود.[۱]

سایر انواع آی اس ای، عبارتند از: معماری‌های کلمه دستورالعمل بسیار بلند (very long instruction word) و معماری‌های بسیار مشابه آن نظیر، کلمه دستورالعمل بلند (long instruction word) و معماری‌های دستورالعمل واضحاً موازی(explicitly parallel instruction computing). هدف از این معماری‌ها بهره‌گیری از موازی گرایی سطح-دستورالعمل با استفاده از سخت‌افزار کمتر در مقایسه با RISC و CISC است. این معماری‌ها برای دستیابی به این هدف، کامپایلر را مسئول مشکلات دستورالعمل و زمان‌بندی می‌کنند.
معماری‌هایی با پیچیدگی‌های حتی کمتر مورد مطالعه قرار گرفته‌اند، نظیر: رایانه با مجموعه دستورالعمل حداقلی (minimal instruction set computer) و رایانه با یک مجموعه دستورالعمل (one instruction set computer). این موارد از لحاظ تئوری اهمیت دارند اما استفاده تجاری نداشته‌اند.

دستورالعمل‌ها

زبان ماشین از عبارت‌ها یا دستورالعمل‌های گسسته تشکیل شده‌است. در معماری پردازش، یک دستورالعمل ممکن است حاوی:

  • آپ کد (opcode)، دستورالعملی که قرار است اجرا شود (مثلاً جمع، کپی، تست)
  • هر گونه عملوند آشکار:
رجیسترها
مقادیر ثابت/ لیترال
حالت‌های آدرس‌دهی مورد استفاده برای دسترسی به حافظه باشند.

با ترکیب کردن این دستورالعمل‌های ساده، که به‌طور متوالی اجرا می‌شوند، یا هدایت توسط دستورالعملهای جریان کنترل، عملیات پیچیده تری تولید می‌شوند.

انواع دستورالعمل

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

مدیریت داده و عملیات حافظه

  • ست کردن یک رجیستر به یک مقدار ثابت
  • کپی کردن داده از یک مکان حافظه یا یک رجیستر به یک مکان حافظه یا یک رجیستر دیگر (یک دستورالعمل ماشین معمولاً move نام دارد، با این حال این اصطلاح گمراه کننده است). برای ذخیره کردن محتوای یک رجیستر، نتیجهٔ یک محاسبه، یا استخراج دادهٔ ذخیره شده برای انجام یک محاسبه بعدی روی آن استفاده می‌شود. این‌ها معمولاً عملیات بارگذاری و ذخیره‌سازی (load and store) نام دارند.
  • خواندن و نوشتن داده از ابزارهای سخت‌افزاری

عملیات محاسباتی و منطقی

  • این عملیات، مقادیر دو رجیستر را جمع، تفریق، ضرب، یا تقسیم می‌کنند و مقدار حاصل را در یک رجیستر قرار می‌دهند، و احتمالاً یک یا بیش از یک کد شرطی را در یک رجیستر وضعیت ست می‌کنند.
    • افزایش مقدار یا کاهش مقدار در برخی آی اس ای‌ها، که موجب حذف استخراج عملوند در موارد جزئی می‌شود.
  • عملیات بیت به بیت را انجام می‌دهند، مثلاً بیت‌های متناظر را در یک جفت رجیستر با یکدیگر AND یا OR می‌کنند یا اینکه مکمل هر بیت در یک رجیستر را به دست می‌آورند.
  • دو مقدار را در رجیسترها با هم مقایسه می‌کنند (برای مثال، برای اینکه بدانند آیا یکی کوچکتر است یا با هم برابرند).
  • دستورالعمل‌های ممیز-شناور برای انجام محاسبات روی اعداد اعشاری

عملیات جریان کنترل

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

دستورالعمل‌های پردازنده‌های فرعی

  • بارگذاری/ذخیره کردن داده از یک پردازنده فرعی یا در یک پردازنده فرعی یا معاوضه با رجیسترهای پردازنده اصلی.
  • انجام عملیات پردازنده فرعی

دستورالعمل‌های پیچیده

پردازنده‌ها ممکن است در مجموعهٔ دستورالعمل خود دارای دستورالعمل‌های پیچیده‌ای باشند. یک دستورالعمل پیچیده ممکن است کاری را انجام دهد که نیاز به دستورالعمل‌های متعددی روی سایر رایانه‌ها است. مشخصه چنین دستورالعمل‌هایی این است که حاوی مراحل متعددی هستند، واحدهای عملکردی متعددی را کنترل می‌کنند، یا اینکه در مقایسه با حجم دستورالعمل‌های ساده ای که توسط پردازندهٔ مورد نظر پیاده‌سازی می‌شوند، مقیاس بزرگ‌تری دارند. برخی مثالهای دستورالعمل‌های پیچیده عبارتند از:
انتقال چندین رجیستر به حافظه یا از حافظه (مخصوصاً پشته) به صورت یکجا.
انتقال بلاک‌های بزرگ از حافظه (مثلاً، کپی کردن رشته یا انتقال از طریق دسترسی مستقیم به حافظه)
محاسبات پیچیده روی اعداد صحیح یا اعداد اعشاری (جذر یا توابع متعالی نظیر: لگاریتم، سینوس، کسینوس، و …)
دستورالعمل‌های نوع یک-دستورالعمل-چندین-داده(Single instruction, multiple data): یک دستورالعمل یک عملیات را روی مقادیر همگن بسیاری، به صورت موازی، و معمولاً در رجیسترهای اختصاصی SIMD انجام می‌دهد.
انجام یک دستورالعمل اتمیک «تست و ست» یا سایر دستورالعمل‌های اتمیک خواندن-تغییر-نوشتن.
دستورالعمل‌هایی که عملیاتی را در ALU با یک عملوند از حافظه و نه از یک رجیستر انجام می‌دهند.

دستورالعمل‌های پیچیده، در مجموعه‌های دستورالعمل CISC، در مقایسه با مجموعه‌های دستورالعمل RISC، بیشتر هستند، اما مجموعه‌های دستورالعمل RISC نیز ممکن است حاوی آنها باشند. مجموعه‌های دستورالعمل RISC، به‌طور کلی، حاوی عملیات ALU با عملگرهای حافظه یا دستورالعمل‌هایی برای انتقال بلوک‌های بزرگ از حافظه نیستند، با این حال، اکثر مجموعه دستورالعمل‌های RISC، حاوی دستورالعمل‌های SIMD یا برداری هستند که عملیات محاسباتی مشابهی را روی قطعات متعددی از داده به صورت همزمان انجام می‌دهند. دستورالعمل‌های SIMD، این قابلیت را دارند که بردارهای بزرگ و ماتریس‌ها را در حداقل زمان دستکاری کنند. دستورالعمل‌های SIMD، قابلیت موازی سازی آسان را برای الگوریتم‌هایی که به‌طور معمول در پردازش صدا، تصویر، و ویدئو یافت می‌شوند، فراهم می‌کنند. پیاده‌سازی‌های متنوعی از SIMD تحت عناوین تجاری مثلاً MMX، 3DNow! و AltiVec وارد بازار شده‌اند.

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

 
یک دستورالعمل ممکن است حاوی چندین قسمت باشد که مشخص کننده عملیات منطقی است و همچنین حاوی آدرس‌های منبع و مقصد و مقادیر ثابت هست. در اینجا دستورالعمل میپس "Add Immediate" نشان داده شده‌است که امکان انتخاب رجیسترهای منبع و مقصد و همچنین جا دادن یک مقدار ثابت را فراهم می‌کند.

در معماری‌های قدیمی، یک دستورالعمل حاوی یک آپ کد است که عملیاتی را که باید انجام گیرد، مثلاً اضافه کردن محتویات حافظه به رجیستر مشخص می‌کند- و همچنین حاوی چند مشخص کنندهٔ عملوندی است که ممکن است رجیسترها، مکان‌های حافظه، یا دادهٔ لیترال را مشخص کنند؛ البته ممکن است این مشخص کننده‌های عملوندی وجود نداشته باشند. این مشخص کننده‌های عملوند ممکن است دارای حالت‌های آدرس دهی باشند که معنی آنها را مشخص می‌کند، یا اینکه در فضاهای ثابت باشند. در معماری‌های کلمه دستورالعمل بسیار بلند (very long instruction word) که حاوی معماری‌های ریز کد بسیاری هستند چندین آپ کد و عملوند به‌طور همزمان در یک دستورالعمل مشخص می‌شوند.
برخی مجموعه‌های دستورالعمل نامعمول، فاقد فضای آپ کد هستند؛ مثلاً در transport triggered architectures، فقط عملوند/عملوندها وجود دارد.
ماشین مجازی Forth و سایر مجموعه‌های دستورالعمل "بدون عملوند"، فاقد فضا برای مشخص کنندهٔ عملوند هستند؛ نظیر برخی ماشین‌های پشته از جمله NOSC.
دستورالعمل‌های شرطی معمولاً دارای یک فضا برای گزاره هستند- گذاره درواقع، چند بیت کوتاه است که شرایط خاصی را کد گذاری می‌کند، که موجب می‌شود یک عملیات انجام شود و نه اینکه انجام نشود. برای مثال، یک دستورالعمل انشعاب شرطی، در صورتیکه شرایط مورد نظر صحیح شود، کنترل را منتقل می‌کند به گونه ای که روند اجرا به بخش متفاوتی از برنامه برود و اگر شرایط غلط باشد کنترل را منتقل نمی‌کند و روند اجرا به شکل متوالی ادامه پیدا می‌کند. همچنین، برخی مجموعه‌های دستورالعمل دارای حرکت‌های شرطی هستند، به گونه ای که اگر شرایط صادق باشد این حرکت اجرا خواهد شد و داده مذکور در مکان مورد نظر ذخیره خواهد شد و اگر شرایط مورد نظر صادق نباشد، اجرا نخواهد شد و مکان مورد نظر نیز تغییر پیدا نخواهد کرد. معماری IBM z/Architecture دارای یک دستورالعمل ذخیره‌سازی شرطی مشابهی است. برخی دستورالعمل‌های معدود حاوی یک فضای گزاره (predicate) در هر دستورالعمل هستند، که گزارهٔ انشعابی نام دارد.

تعداد عملوندها

مجموعه‌های دستورالعمل ممکن است بر مبنای حداکثر تعداد عملوندهایی که به‌طور آشکار در دستورالعمل‌ها مشخص می‌شوند طبقه‌بندی شوند.
(در مثال زیر a , b و c، در واقع، آدرس‌های (مستقیم یا محاسبه شده) هستند که به سلول‌های حافظه ارجاع می‌شوند، در حالیکه، reg1 و موارد مشابه، همان رجیسترهای ماشین هستند)

C = A+B

  • صفر-عملوند (ماشین‌های فاقد آدرس) یا همان ماشین‌های پشته: تمام عملیات محاسباتی با استفاده از عنصر بالای پشته یا دو موقعیت در پشته رخ می‌دهند: push a, push b, add, pop c.
    • عمل C = A+B نیازمند چهار دستورالعمل است. برای ماشین‌های پشته اصطلاحات «صفر-عملوند» و «صفر-آدرس» به عملیات محاسباتی اطلاق می‌شوند و به تمام دستورالعمل‌ها اطلاق نمی‌شوند، زیرا دستورالعمل‌های تک-عملوندی push و pop برای دسترسی به حافظه استفاده می‌شوند.
  • یک-عملوند (ماشین‌های تک آدرسی) یا همان ماشین‌های جمع‌کننده، که شامل رایانه‌های ابتدایی و بسیاری از میکروکنترلرهای کوچک می‌شود: اکثر دستورالعمل‌ها یک عملوند سمت راست (یک ثابت، رجیستر یا مکان حافظه) را، همراه با جمع‌کننده ی ضمنی به عنوان عملوند سمت چپ (و مقصد، درصورتیکه تنها باشد) مشخص می‌کنند: load a, add b, store c
    • عملیات C = A+B نیازمند سه دستورالعمل است.
  • دو عملوند- بسیاری از ماشین‌های CISC و RISC تحت این مقوله قرار می‌گیرند.
    • معماری CISC: ابتدا a را به c منتقل کن، سپس b را به c اضافه کن.
      • عملیات C = A+B نیازمند دو دستورالعمل است، که به شکل مؤثری، و بدون نیاز به یک دستورالعمل ذخیره‌سازی آشکار، نتیجه را ذخیره می‌کند.
    • معماری CISC- معمولاً ماشین‌ها محدود به یک عملوند حافظه به ازای هر دستورالعمل هستند: load a,reg1; add b,reg1; store reg1,c که نیازمند یک جفت بارگذاری/ذخیره برای هر گونه انتقال حافظه است، که جدا از این است که آیا حاصل add، یک افزایش است که در مکان متفاوتی ذخیره شده‌است، مثلاً در C = A+B، یا این که در مکان مشابهی از حافظه ذخیره شده‌است:A = A+B ،
      • عملیات C = A+B نیازمند سه دستورالعمل است.
    • معماری RISC- نیازمند بارگذاری‌های آشکار حافظه است و دستورالعمل‌ها به فرم load a,reg1; load b,reg2; add reg1,reg2; store reg2,c خواهند بود.

عملیات C = A+B نیازمند چهار دستورالعمل است.

  • سه-عملوند، که امکان استفاده مجدد بهتری از داده را فراهم می‌کند.[۲]
    • معماری CISC- یا یک دستورالعمل می‌شود: add a,b,c

عملیات C = A+B نیازمند یک دستورالعمل است.

    • معماری CISC- یا روی ماشین‌های محدود به دو عملوند حافظه به ازای هر دستورالعمل،

move a,reg1; add reg1,b,c;

      • عملیات C = A+B نیازمند دو دستورالعمل است.
    • معماری RISC- دستورالعمل‌های محاسباتی فقط از رجیسترها استفاده می‌کنند، بنابراین نیاز به دستورالعمل‌های آشکار دو-عملوندی بارگذاری/ذخیره داریم: load a,reg1; load b,reg2; add reg1+reg2->reg3; store reg3,c
      • عملیات C = A+B نیازمند چهار دستورالعمل است.
      • برخلاف دو-عملوند یا یک-عملوند، این حالت اجازه می‌دهد تا هر سه مقدار a, b، و c برای استفاده مجدد بیشتر، در رجیسترها موجود باشند.
  • عملوندهای بیشتر-برخی ماشین‌های CISC، اجازهٔ انواعی از حالت‌های آدرس دهی را می‌دهند که امکان استفاده از بیش از سه عملوند را فراهم می‌کند (رجیسترها یا دسترسی‌های حافظه)، مثلاً: دستورالعمل ازیابی چند جمله ای VAX "POLY".

به دلیل تعداد زیاد بیت‌های مورد نیاز برای کدگذاری سه رجیستر یک دستورالعمل سه-عملوندی، معماری‌های RISC که دارای دستورالعمل‌های ۱۶ بیتی هستند، تماماً دارای طراحی‌های دو-عملوندی هستند، نظیر: Atmel AVR, TI MSP43 و برخی نسخه‌های ARM Thumb. معماری‌های RISC که دارای دستورالعمل‌های ۳۲ بیتی هستند، معمولاً دارای طراحی‌های سه-عملوندی هستند، نظیر: ARM, AVR32, MIPS, Power آی اس ای و معماری‌های SPARC.
هر دستورالعمل تعدادی عملوند (رجیسترها، مکان‌های حافظه، یا مقادیر فوری) را "به طور آشکار" مشخص می‌کند. برخی دستورالعمل‌ها یک یا بیش از یک عملوند را به‌طور ضمنی فراهم می‌کنند، مثلاً از طریق ذخیره شدن در بالای یک پشته، یا در یک رجیستر غیر مستقیم. در حالتی که برخی از عملوندها به‌طور ضمنی داده می‌شوند، به عملوندهای کمتری در دستورالعمل نیاز هست. هنگامی که یک "عملوند مقصد" به‌طور آشکار مقصد را مشخص می‌کند، باید عملوند دیگری نیز فراهم شود. در نتیجه تعداد عملوندهای کدگذاری شده در یک دستورالعمل، ممکن است با تعداد آرگومان‌های مورد نیاز از نظر ریاضی برای یک عملیات منطقی یا محاسباتی (arity) تفاوت داشته باشد. عملوندها یا در نمایش "آپ کد" دستورالعمل، کدگذاری می‌شوند یا اینکه به صورت مقادیر یا آدرس، به دنبال آپ کد می‌آیند.

فشار رجیستر

فشار رجیستر نمایانگر تعداد رجیسترهای آزاد در هر زمان از اجرای برنامه است. فشار رجیستر، زمانی که تعداد زیادی از رجیسترهای موجود در حال استفاده هستند بالاست؛ بنابراین هر قدر فشار رجیستر بالاتر باشد، به تعداد دفعات بیشتری لازم است تا محتویات رجیستر به داخل حافظه سرریز شود. افزایش تعداد رجیسترها در یک معماری موجب کاهش فشار رجیستر می‌شود، اما هزینه را افزایش می‌دهد.[۳]

در حالی که مجموعه‌های دستورالعمل نهفته نظیر Thumb از فشار بسیار بالای رجیستر به دلیل تعداد کم مجموعه رجیستر رنج می‌برند، اما معماری‌های مجموعه دستورالعمل RISC عمومی نظیر MIPS و Alpha دارای فشار رجیستر پایینی هستند. معماری‌های مجموعه‌های دستورالعمل CISC، همچون x86-64، علی‌رغم داشتن مجموعه رجیستر کوچکتر دارای فشار رجیستر کمتری هستند. دلیل این امر وجود تعداد زیادی حالت‌های آدرس دهی و بهینه‌سازی (نظیر آدرس‌دهی تحت رجیستر، عملوندهای حافظه در دستورالعمل‌های ALU، آدرس دهی مستقیم، آدرس دهی مرتبط با شمارنده برنامه و سرریزهای رجیستر-به-رجیستر) است که توسط معماری‌های مجموعه دستورالعمل CISC ارائه می‌شوند.[۴]

طول دستورالعمل

اندازه یا طول یک دستورالعمل می‌تواند بسیار متفاوت باشد؛ از یک مقدار چهار بیتی در برخی میکروکنترلرها تا چند صد بیت در برخی سیستم‌های VLIW. پردازنده‌های مورد استفاده در رایانه‌های شخصی، رایانه‌های بزرگ و ابر رایانه‌ها، دارای اندازه دستورالعمل بین ۸ و ۶۴ بیت هستند. حداکثر اندازه ممکن برای دستورالعمل در x86 برابر با ۱۵ بایت (۱۲۰ بیت) است.[۵] Within an instruction set, different instructions may have different در داخل یک مجموعه دستورالعمل، دستورالعمل‌های مختلف، ممکن است طول متفاوت داشته باشند. در برخی معماری‌ها، نظیر اکثر RISCها، دستورالعمل‌ها دارای طول ثابتی هستند که معمولاً مطابق با اندازهٔ کلمه آن معماری می‌باشند. در معماری‌های دیگر، دستورالعمل‌ها دارای طول متغیر هستند، که معمولاً مضرب‌های صحیح از یک بایت یا یک نیم کلمه هستند. برخی معماری‌ها نظیر ARM با Thumb-extension، دارای کدگذاری متغیر ترکیبی است که دو کدگذاری ثابت، معمولاً ۳۲ بیت و ۱۶ بیت است، که در آن، دستورالعمل‌ها را نمی‌توان به شکل آزادانه با هم ترکیب کرد، و باید در یک انشعاب (یا محدوده استثنا در ARMv8)، بین آنها تعویض انجام شود.

یک مجموعه دستورالعمل RISC، معمولاً دارای طول دستورالعمل ثابتی است (معمولاً چهار بایت که معادل ۳۲ بیت است)، در حالیکه مجموعه دستورالعمل CISC ممکن است دارای دستورالعمل‌هایی با طول بسیار متغیر باشند(۱ تا ۱۵ بایت برای x86). مدیریت دستورالعمل‌های دارای طول ثابت در مقایسه با دستورالعمل‌های با طول متغیر، به دلایل مختلفی پیچیدگی کمتری دارد (برای مثال، لازم نیست که چک کنیم که آیا یک دستورالعمل از یک خط حافظه پنهان یا محدودهٔ صفحه حافظه مجازی عبور کرده‌است یا خیر)، و بنابراین برای بهینه‌سازی، تا حدودی سرعت آسان‌تر هستند.

تراکم کد

در رایانه‌های قدیمی حافظه گران‌قیمت بود؛ بنابراین به حداقل رساندن اندازهٔ برنامه، معمولاً اهمیت زیادی داشت تا بتوان آن را در حافظهٔ محدود جا داد؛ لذا سایز ترکیبی تمام دستورالعمل‌های لازم برای انجام یک کار خاص، یا همان تراکم کد، مشخصهٔ مهمی برای هر مجموعه دستورالعمل بود. رایانه‌های دارای تراکم کد بالا، معمولاً دارای دستورالعمل‌های پیچیده برای ورودی رویه، بازگشت‌های پارامتر شده، حلقه‌ها، و … بودند (بنابراین، به صورت عطف به ماسبق، CISC نامیده می‌شدند). با این حال، دستورالعمل‌های معمول تر یا پرکاربرد CISC، صرفاً یک عملیات پایه ای ALU، نظیر جمع کردن، را با دسترسی به یک یا بیش از یک عملوند در حافظه (با استفاده از حالت‌های آدرس دهی مختلف همچون، مستقیم و غیر مستقیم، اندکسی و …) ترکیب می‌کنند. معماری‌های خاصی ممکن است اجازه دو یا سه عملوند (ازجمله حاصل) را به‌طور مستقیم در حافظه بدهند یا ممکن است قادر باشند اعمالی همچون افزایش خودکار اشاره گر و … را انجام دهند مجموعه دستورالعمل‌های که توسط نرم‌افزار پیاده‌سازی می‌شوند، ممکن است حتی، دستورالعمل‌های پیچیده‌تر و قدرتمند تری داشته باشند.

رایانه‌های با مجموعه دستورالعمل کاهش یافته، RISC، برای اولین بار، به‌طور گسترده در زمان رشد سریع زیر سیستم‌های حافظه پیاده‌سازی شدند. آنها تراکم کد را قربانی می‌کنند تا مدار پیاده‌سازی را ساده کنند و سعی می‌کنند عملکرد را از طریق فرکانسهای بالاتر ساعت و رجیسترهای بیشتر افزایش دهند. یک دستورالعمل RISC، به‌طور معمول فقط یک عملیات انجام می‌دهد، نظیر «جمع» کردن رجیسترها یا «بارگذاری» از یک مکان حافظه به داخل یک رجیستر. یک مجموعه دستورالعمل RISC، به‌طور معمول، دارای طول دستورالعمل ثابت است، در حالی که یک مجموعه دستورالعمل معمول CISC، دارای دستورالعمل‌هایی با طول بسیار متغیر است. با این حال، از آنجایی که رایانه‌های RISC، به‌طور معمول، نیازمند دستورالعملهای بیشتر و معمولاً طولانی‌تر برای پیاده‌سازی یک کار خاص هستند، لذا به‌طور ذاتی استفاده بهینه کمتری از پهنای باند گذرگاه و حافظه‌های نهان می‌کنند.

برخی معماری‌های مجموعه دستورالعمل RISC نهفته(embedded)، نظیر Thumb و AVR32 به‌طور معمول دارای تراکم بسیار بالایی هستند، که علت آن وجود یک تکنیک به نام «فشرده سازی کد» در آن‌ها است. این تکنیک دو دستورالعمل ۱۶ بیتی را در کنار هم در داخل یک کلمه ۳۲ بیتی بسته‌بندی می‌کند و سپس در مرحله کدگشایی، بسته‌بندی باز می‌شود و به شکل دو دستورالعمل اجرا می‌شود.[۶]

رایانه‌ها با مجموعه دستورالعمل حداقل (Minimal instruction set computers)، فرمی از ماشین پشته هستند که در آن تعداد اندکی دستورالعمل مجزا (۱۶ تا ۶۴) وجود دارد، به گونه‌ای که چندین دستورالعمل را می‌توان در داخل یک کلمه ماشین جا داد. این نوع از هسته‌ها معمولاً برای پیاده‌سازی، نیاز به سیلیکون کمتری دارند؛ بنابراین، می‌توان آنها را به راحتی به فرم یک آرایهٔ درگاهی برنامه پذیر (field-programmable gate array) یا چند هسته ای درآورد. تراکم کد MISC مشابه تراکم کد RISC است. مزیت تراکم بیشتر دستورالعمل، با وجود نیاز به دستورالعمل‌های بدوی بیشتر برای انجام یک کار، خنثی می‌شود.
تحقیقاتی در رابطه با فشرده سازی قابل اجرا به عنوان یک مکانیسم برای بهبود تراکم کد انجام گرفته‌است. ریاضیات پیچیدگی کولموگروف، چالش‌ها و محدودیت‌های این مکانیسم را توصیف می‌کند.

نمایش

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

طراحی

طراحی مجموعه‌های دستورالعمل یک مسئله پیچیده‌است. دو مرحله در تاریخ، برای ریزپردازنده‌ها وجود داشته‌است. در اولین مرحله، رایانه‌های دارای مجموعه دستورالعمل پیچیده (CISC) بودند، که دارای دستورالعمل‌های مختلف بسیاری بود. با این حال، در دهه ۱۹۷۰ مکان‌هایی نظیر IBM، تحقیقاتی را انجام دادند و دریافتند که بسیاری از دستورالعمل‌های این مجموعه را می‌توان حذف کرد. نتیجه آن، رایانه‌های دارای مجموعه دستورالعمل کاهش یافته (RISC) بود که نوعی معماری است که از یک مجموعهٔ کوچکتر از دستورالعمل‌ها استفاده می‌کند. یک مجموعه دستورالعمل ساده‌تر، به‌طور بالقوه می‌تواند موجب سرعت‌های بیشتر، کاهش اندازه پردازنده، و کاهش مصرف انرژی شود. با این حال، یک مجموعهٔ پیچیده‌تر، ممکن است عملیات رایج را بهینه‌سازی کند، کارایی حافظه و حافظهٔ نهان را افزایش دهد، یا برنامه‌نویسی را ساده کند.
برخی طراحان مجموعه دستورالعمل، یک یا بیش از یک آپ کد را برای انواعی از فراخوانی‌های سیستم یا وقفه‌های نرم‌افزاری رزرو می‌کنند. برای مثال، MOS Technology 6502 از 00H استفاده می‌کند و Zilog Z80 از هشت کد C7,CF,D7,DF,E7,EF,F7,FFH استفاده می‌کنند،[۷] در حالیکه Motorola 68000 از کدهایی در محدودهٔ A000..AFFFH استفاده می‌کند.
اگر یک مجموعه دستورالعمل، ملزومات مجازی سازی پوپک و گلدبرگ (Popek and Goldberg virtualization requirements) را برآورده کند، آنگاه پیاده‌سازی ماشین‌های مجازی سریع، بسیار آسان‌تر خواهد بود.
اگر وضعیت «برنامه‌نویسی نشده ی» حافظه به شکل دستورالعمل تهی (NOP) تفسیر شود، آن گاه پیاده‌سازی NOP slide که در immunity-aware programming استفاده شده‌است، بسیار آسان‌تر خواهد بود.
اگر مجموعه دستورالعمل قادر به پشتیبانی از قابلیت‌هایی نظیر استخراج و جمع(fetch-and-add)، بارگیری-لینک/ذخیره‌سازی-مشروط(load-linked/store-conditional)، یا عمل مقایسه و جابجایی(compare-and-swap) اتمیک باشد، آنگاه در یک سیستم با چندین پردازنده، پیاده‌سازی الگوریتم‌های همگام سازی غیر مسدودکننده، بسیار آسان‌تر خواهد بود.

پیاده‌سازی مجموعه دستورالعمل

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

مهندسان در هنگام طراحی کردن ریز معماری یک پردازنده، از قطعات مدار الکترونیکی شش میخ شده(hard-wired) (که معمولاً به‌طور جداگانه طراحی می‌شوند)، همچون جمع‌کننده‌ها، مالتی پلکسرها، شمارنده‌ها، رجیسترها، ALUها و … استفاده می‌کنند. سپس معمولاً از انواعی از زبان‌های انتقال رجیستر (register transfer language) برای توصیف کدگشایی و توالی بندی هر دستورالعمل آی اس ای، با استفاده از این ریز معماری فیزیکی استفاده می‌شود. دو روش اساسی برای ساختن یک واحد کنترل(control unit) برای پیاده‌سازی این توصیفات وجود دارد (اگرچه بسیاری از طراحی‌ها از شیوه‌های بینابین استفاده می‌کنند).

  • ۱. برخی طراحی‌های رایانه، تمام کد گشایی و توالی بندی مجموعه دستورالعمل را شش میخ می‌کنند، درست شبیه مابقی ریز معماری.
  • ۲. طراحی‌های دیگر از روتین‌های ریزکد یا جداول (یا هر دو) برای این کار استفاده می‌کنند- به‌طور معمول به شکل ROM‌های روی چیپ یا PLAها یا هر دو (اگرچه به‌طور تاریخی RAMها و ROMهای جداگانه استفاده شده‌اند). Western Digital MCP-1600 یک مثال قدیمی است که از یک ROM اختصاصی مجزا برای میکرو کد استفاده می‌کند.

برخی طراحی‌ها از ترکیبی از طراحی شش میقه و میکروکد برای واحد کنترل استفاده می‌کنند. برخی طراحی‌های پردازنده از یک مخزن کنترل قابل نوشتن (writable control store) استفاده می‌کنند- آنها مجموعه دستورالعمل مورد نظر را در یک RAM قابل نوشتن یا فلش، در داخل پردازنده (مثلاً پردازنده Rekursiv) یا یک FPGA (رایانش قابل پیکربندی) کامپایل می‌کنند.[۸]

یک آی اس ای را می‌توان در نرم‌افزار با استفاده از یک تفسیرگر شبیه‌سازی کرد. به‌طور طبیعی، به دلیل سربار ناشی از تفسیر، این روش کندتر از اجرای مستقیم برنامه‌ها روی سخت‌افزار شبیه‌سازی شده‌است، مگر اینکه سخت‌افزاری که شبیه‌ساز را اجرا می‌کند، چندین برابر سریع تر باشد. امروزه به‌طور رایجی، فروشندگان آی اس ایها یا ریز معماری‌های جدید، شبیه‌سازهای نرم‌افزاری را پیش از آماده شدن پیاده‌سازی سخت‌افزاری، در اختیار توسعه دهندگان نرم‌افزار قرار می‌دهند.
معمولاً جزئیات پیاده‌سازی مورد نظر، تأثیر بسیاری روی دستورالعمل‌های خاص انتخاب شده برای مجموعه دستورالعمل مورد نظر دارند. برای مثال، بسیاری از پیاده‌سازی‌های خط لوله دستورالعمل، فقط اجازه می‌دهند تا یک بارگذاری حافظه یا ذخیره‌سازی حافظه به ازای هر دستورالعمل انجام شود، که منجر به معماری بارگیری-ذخیره‌سازی (RISC) می‌شود. به عنوان مثال دیگر، برخی روش‌های ابتدایی پیاده‌سازی خط لوله دستورالعمل، منجر به یک درگاه تأخیر (delay slot) شد.

نیاز روزافزون به پردازش سیگنال دیجیتال با سرعت بالا، جهت رویه را معکوس کرده‌است و باعث شده‌است تا پیاده‌سازی دستورالعمل‌ها به شیوه‌های خاصی انجام گیرد. برای مثال، دستورالعمل MACH در یک پردازشگر سیگنال دیجیتال، برای انجام سریع فیلترهای دیجیتال، باید از یک نوع معماری هاروارد استفاده کند، که به‌طور همزمان یک دستورالعمل و دو کلمه داده را استخراج می‌کند و نیازمند یک ضرب کنندهٔ ضرب کن-جمع کن (multiply–accumulate) تک چرخه ای است.

جستارهای وابسته

منابع

  1. Crystal Chen; Greg Novick; Kirk Shimano (December 16, 2006). "RISC Architecture: RISC vs. CISC". cs.stanford.edu. Retrieved February 21, 2015.
  2. The evolution of RISC technology at IBM by John Cocke – IBM Journal of R&D, Volume 44, Numbers 1/2, p.48 (2000)
  3. Page, Daniel (2009). "11. Compilers". A Practical Introduction to Computer Architecture. Springer. p. 464. Bibcode:2009pica.book.....P. ISBN 978-1-84882-255-9.
  4. Venkat, Ashish; Tullsen, Dean M. (2014). Harnessing ISA Diversity: Design of a Heterogeneous-ISA Chip Multiprocessor. 41st Annual International Symposium on Computer Architecture.
  5. "Intel® 64 and IA-32 Architectures Software Developer's Manual". Intel Corporation. Retrieved 12 July 2012.
  6. Weaver, Vincent M.; McKee, Sally A. (2009). Code density concerns for new architectures. IEEE International Conference on Computer Design. CiteSeerX 10.1.1.398.1967. doi:10.1109/ICCD.2009.5413117.
  7. Ganssle, Jack (February 26, 2001). "Proactive Debugging". embedded.com.
  8. "Great Microprocessors of the Past and Present (V 13.4.0)". cpushack.net. Retrieved 2014-07-25.

مشارکت‌کنندگان ویکی‌پدیا. «Instruction set». در دانشنامهٔ ویکی‌پدیای انگلیسی، بازبینی‌شده در ۱۲ آوریل ۲۰۲۱.