زبان اسمبلی اکس۸۶
زبان اسمبلی x86 خانواده ای از زبان‌های اسمبلی دارای سازگاری عقبرو است که حتی با Intel 2088 که در آوریل ۱۹۷۲ معرفی شد، تا حدودی سازگاری دارد. زبان‌های اسمبلی x86 برای تولید کد هدف برای پردازنده‌های کلاس x86 استفاده می‌شوند. زبان اسمبلی x86 همانند تمام زبان‌های اسمبلی، از یادیارهای کوتاه استفاده می‌کند تا دستورالعمل‌های اساسی را که CPU در یک کامپیوتر می‌تواند درک و دنبال کند، نشان دهد. کامپایلرها گاهی هنگام ترجمهٔ یک برنامه سطح بالا به کد ماشین، کد اسمبلی را به عنوان یک مرحله میانی تولید می‌کنند.
به عنوان یک زبان برنامه‌نویسی، اسمبلی به "صورت خاص" "ماشین" و "سطح پایین" است. زبان‌های اسمبلی به‌طور معمول برای برنامه‌های کاربردی دقیق و زمان بحرانی مورد استفاده قرار می‌گیرند مانند سیستم‌های نهفتهٔ بلادرنگ یا هسته‌های سیستم عامل و درایورهای دستگاه.
اینتل ۸۰۸۶ و ۸۰۸۸ اولین پردازنده‌هایی بودند که یک مجموعه دستورالعمل داشتند که در حال حاضر معمولاً آن را x86 می‌نامند.
این پردازنده‌های ۱۶ بیتی که تکامل یافتهٔ نسل قبلی پردازنده‌های ۸ بیتی مانند ۸۰۸۰ بودند، ویژگی‌ها و دستورالعمل‌های بسیاری را از آن‌ها به ارث برده و برای نسل ۱۶ بیتی توسعه داده‌اند. ۸۰۸۶ و ۸۰۸۸ هر دو از گذرگاه آدرس ۲۰ بیتی و ثبات‌های داخلی ۱۶ بیتی استفاده می‌کردند؛ اما تفاوت‌هایی نیز داشتند، برای مثال، در حالی که ۸۰۸۶ دارای یک گذرگاه داده ۱۶ بیتی بود، ۸۰۸۸، به عنوان یک گزینهٔ کم هزینه تر برای برنامه‌های کاربردی نهفته و کامپیوترهای کوچک، از یک گذرگاه دادهٔ ۸ بیتی بهره می‌برد.
زبان اسمبلی x86 انواع مختلفی از CPUها را پوشش می‌دهد از جمله: پردازنده‌های اینتلی مانند 80186، 80188، ۸۰۲۸۶، ۸۰۳۸۶، 80486، پنتیوم، پنتیوم پرو و غیره و همچنین پردازنده‌های غیر اینتلی AMD و Cyrix مانند پردازنده‌های 5x86 و K6 و NEC V20 (هرچند این پردازنده‌ها غالباً سازگار با اینتل هستند، دستورالعمل‌هایی را که ممکن است به سختی بخشی از زبان اسمبلی x86 در نظر گرفته شود را به مجموعه دستورالعمل‌های خود اضافه کرده‌اند؛ همانند دستورالعمل‌هایی که Zilog به Z80 اضافه کرد) اصطلاح x86 برای هر پردازنده ای که می‌تواند زبان اسمبلی اصلی را اجرا کند، مورد استفاده قرار می‌گیرد.
مجموعهٔ جدید دستورالعمل‌های x86، یک ابرمجموعه از دستورالعمل‌های ۸۰۸۶ و مجموعه ای از افزونه‌های اضافه شده به این دستورالعمل هاست که از میکروپروسسور اینتل ۸۰۰۸ آغاز شد. سازگاری عقبرو باینری تقریباً کاملی میان تراشهٔ اینتل از ۸۰۸۶ تا نسل فعلی پردازنده‌های x86 وجود دارد، اگر چه برخی از استثنائات وجود دارند. در عمل، استفاده از دستورالعمل‌هایی که روی هر پردازنده ای از اینتل ۸۰۳۸۶ یا پنتیوم به بعد اجرا شود، رایج است. اما در سال‌های اخیر، سیستم عامل‌های مختلف و برنامه‌های کاربردی نرم‌افزار به نیاز به پردازنده‌های مدرن تر پیدا کرده‌اند، پردازنده‌هایی که دست کم از تعدادی از افزونه‌هایی که به مجموعهٔ دستورالعمل‌ها اضافه شده‌اند، پشتیبانی کنند. (به عنوان مثال MMX، 3DNow!، SSE / SSE2 / SSE3).
هر دستورالعمل مونتاژ x86 با یک یادیار نشان داده می‌شود که اغلب با یک یا چند عملوند ترکیب شده‌است و به یک یا چند بایت به نام آپ کد ترجمه می‌شود؛ به عنوان مثال دستور NOP به 0x90 ترجمه می‌شود و دستور HLT به 0xF4 ترجمه می‌شود. آپ کد‌های بالقوه ای وجود دارند که هیچ یادیار مستندی برای آن‌ها وجود ندارد. پردازنده‌های مختلف ممکن است این آپ کد‌ها را به‌طور متفاوتی از یکدیگر تفسیر کنند، برنامه ای که با استفاده از آن‌ها ایجاد شود، متناقض رفتار خواهد کرد یا حتی در برخی از پردازنده‌ها یک استثنا ایجاد می‌کند. این آپ کد‌ها اغلب در مسابقه‌های کدنویسی به عنوان راهی برای کوچکتر، سریع تر و ظریف تر کردن کد استفاده می‌شوند یا تنها نشان دهندهٔ مهارت کدنویس می‌باشند.
زبان اسمبلی x86 دارای دو شاخهٔ اصلی نحو است: "نحو اینتل"، که در اصل برای مستندسازی پلت فرم x86 استفاده می‌شود، و "نحو AT & T." استفاده از "نحو اینتل" در دنیای MS-DOS و ویندوز غالب است و استفاده از "نحو AT & T" در دنیای یونیکس، از آنجایی که یونیکس در آزمایشگاه‌های AT & T Bell ایجاد شده‌است. در اینجا خلاصه ای از تفاوت‌های اصلی میان "نحو اینتل" و "نحو" "AT & T" آمده‌است:
بسیاری از اسمبلرهای x86 از "نحو اینتل" استفاده می "کنند"، از جمله NASM, FASM ,MASM ,TASM و YASM. اسمبلر GAS از نسخهٔ ۲٫۱۰ به بعد از طریق دایرکتیو .intel_syntax از هر دو نحو پشتیبانی می‌کند.
پردازنده‌های x86 دارای مجموعه ای از ثبات‌ها هستند که برای ذخیره‌سازی داده‌های باینری استفاده می‌شوند. در مجموع، ثبات‌های داده و ثبات‌های آدرس، ثبات‌های عمومی نامیده می‌شوند. هر ثباتی به جز آنچه که همهٔ ثبات‌ها می‌توانند انجام دهند، هدف خاصی نیز دارد:
علاوه بر ثبات‌های عمومی، موارد زیر نیز وجود دارند:
ثبات‌های x86 می‌توانند همراه دستورالعمل‌های MOV استفاده شوند. به عنوان مثال، در نحو اینتل: mov ax, 1234h ; copies the value 1234hex (4660d) into register AXmov bx, ax ; copies the value of the AX register into the BX register
معماری x86 در وضعیت حقیقی و مجازی ۸۰۸۶ از یک فرایند به نام قطعه بندی (به جای مدل حافظهٔ مسطح که در بسیاری از محیط‌های دیگر استفاده می‌شود) برای آدرس دهی حافظه استفاده می‌کند. قطعه بندی، شامل ساخت یک آدرس حافظه از دو بخش است: یک قطعه و یک افست؛ قطعه به نقطهٔ شروع یک گروه ۶۴ کیلوبایتی از آدرس‌ها اشاره می‌کند و افست تعیین می‌کند که آدرس مورد نظر در چه فاصله ای از این نقطهٔ شروع قرار دارد. در آدرس دهی قطعه بندی شده، برای ثبت آدرس کامل حافظه، دو رجیستر نیاز است. یکی برای نگه داشتن قطعه و دیگری برای نگه داشتن افست. به منظور ترجمه به یک آدرس مسطح؛ مقدار قطعه، چهار بیت به چپ (که معادل است با ضرب در 2 یا ۱۶) شیفت داده می‌شود و سپس به مقدار افست اضافه می‌شود تا آدرس کامل را ایجاد کند. این روش اجازه می‌دهد محدودیت آدرس دهی ۶۴ کیلوبایتی را از طریق انتخاب هوشمندانهٔ آدرس‌ها دور بزنیم. هرچند که برنامه‌نویسی را به مراتب پیچیده‌تر می‌کند.
برای مثال، در وضعیت حقیقی/محافظت شده، اگر DS حاوی مقدار هگزادسیمال 0xDEAD بوده و DX حاوی مقدار 0xCAFE باشد، ای دو در کنار هم به آدرس حافظهٔ 0xDEAD * 0x10 + 0xCAFE = 0xEB5CE اشاره می‌کنند؛ بنابراین، CPU می‌تواند تا ۱۰۴۸۵۷۶ بایت (۱ مگابایت) را در وضعیت حقیقی آدرس دهی کند. با ترکیب مقادیر "قطعه" و "افست،" یک آدرس ۲۰ بیتی را خواهیم داشت.
کامپیوتر اصلی آی بی ام برنامه‌ها را محدود به ۶۴۰ کیلوبایت می‌کرد، اما مشخصات حافظه گسترش یافته برای پیاده‌سازی یک طرح سوئیچینگ بانکی که سقوط از استفاده از زمانی که بعد از سیستم عامل، مانند ویندوز، استفاده از محدوده آدرس بزرگتر از پردازنده‌های جدید و استفاده از حافظه مجازی خود طرح‌ها
حالت محافظت شده، که از اینتل ۸۰۲۸۶ آغاز شد، توسط OS / 2 مورد استفاده قرار گرفت. نقطه ضعف‌هایی مانند عدم قابلیت دسترسی به BIOS و عدم توانایی برای بازگشت به حالت واقعی بدون تنظیم مجدد پردازنده، مانع استفادهٔ گستردهٔ آن شد. ۸۰۲۸۶ همچنان محدود به آدرس دهی حافظه در بخش‌های ۱۶ بیتی بود، به این معنی که فقط 2 بایت (۶۴ کیلوبایت) در هر لحظه قابل دسترسی بود. برای دسترسی به قابلیت‌های گسترش یافتهٔ ۸۰۲۸۶، سیستم عامل، پردازنده را روی حالت محافظت شده تنظیم می‌کند، بنابراین آدرس دهی ۲۴ بیتی و نتیجتاً دسترسی به 2 بایت (۱۶ مگابایت) حافظه را امکان‌پذیر می‌کند.
در حالت محافظت شده، انتخابگر قطعه را می‌توان به سه بخش تقسیم کرد: یک شاخص ۱۳ بیتی، یک "نشانگر جدول" یک بیتی که تعیین می‌کند ورودی در GDT قرار دارد یا در LDT و یک "سطح مجوز درخواستی" ۲ بیتی.
در هنگام اشاره به یک آدرس مشخص شده با یک قطعه و یک افست، از نشانه گذاری قطعه:افست استفاده می‌شود، بنابراین در مثال فوق، "آدرس مسطح" 0xEB5CE می‌تواند یا به صورت 0xDEAD:0xCAFE نوشته شود یا به صورت یک جفت ثبات که یکی برای قطعه و دیگری برای افست است؛ DS:DX.
اینتل ۸۰۳۸۶ دارای سه حالت کارکرد می‌باشد: حالت واقعی، حالت محافظت شده و حالت مجازی. حالت محافظت شده که در ۸۰۲۸۶ عرضه شد، به ۸۰۳۸۶ این امکان را می‌دادکه تا حداکثر ۴ گیگابایت حافظه در اختیار داشته باشد؛ حالت مجازی جدید 8086 ("VM86")، اجرای یک یا چند برنامهٔ حالت واقعی را در یک محیط محافظت شده که عمدتاً مشابه حالت واقعی بود، امکان‌پذیر کرد، هر چند برخی از برنامه‌ها با این حالت سازگار نبودند.
مدل حافظه مسطح ۳۲ بیتی در حالت حفاظت شدهٔ توسعه یافتهٔ ۸۰۳۸۶، احتمالاً مهم‌ترین ویژگی تغییر یافته در خانوادهٔ پردازنده x86 بود تا زمانی که ای ام دی، x86-64 را در سال ۲۰۰۳ منتشر کرد، ویندوز اکنون می‌تواند بسیاری از برنامه‌های کاربردی، از جمله برنامه‌های DOS، را با استفاده از حافظهٔ مجازی و چند اجرای توامان، به صورت هم‌زمان اجرا کند.
پردازنده‌های x86 از پنج حالت عملکرد پشتیبانی می‌کنند: حالت حقیقی، حالت محافظت شده، حالت طولانی، حالت مجازی ۸۶ و حالت مدیریت سیستم، که در هر کدام از این حالت‌ها برخی دستورالعمل‌ها در دسترس بوده و برخی دیگر در دسترس نخواهند بود. یک زیر مجموعهٔ ۱۶ بیتی از دستورالعمل‌ها در حالت حقیقی در تمام پردازنده‌های x86 قابل استفاده هستند و در حالت محافظت شدهٔ ۱۶ بیتی (از ۸۰۲۸۶ به بعد) دستورالعمل‌های افزدوه شده مربوط به حالت محافظت شده هم در دسترس هستند. در ۸۰۳۸۶ و پردازنده‌های بعد از آن، دستورالعمل‌های ۳۲ بیتی نیز در همهٔ حالت‌ها، از جمله حالت واقعی قابل استفاده هستند. در این پردازنده‌ها، حالت V86 و حالت حفاظت شدهٔ ۳۲ بیتی، همراه با دستورالعمل‌های اضافی ارائه شده در این حالت‌ها برای مدیریت امکانات این پردازنده‌ها، اضافه شده‌اند. SMM، با برخی از دستورالعمل خاص خود، در برخی از پردازنده‌های اینتل i386SL , i486 و بعد از این‌ها در دسترس است. در حالت طولانی (از ای ام دی Opteron به بعد)، دستورالعمل‌های ۶۴ بیتی و ثبات‌های بیشتری نیز در دسترس هستند. مجموعهٔ دستورالعمل‌ها در همهٔ حالت‌ها مشابه هم هستند اما آدرس دهی حافظه و اندازهٔ کلمات متفاوتند؛ در نتیجه برنامه‌نویسی در حالت‌های مختلف نیاز به استراتژی‌های برنامه‌نویسی متفاوت دارد.
کد x86 می‌تواند در حالت‌های زیر اجرا شود:
پردازنده بلافاصله پس از روشن شدن در حالت واقعی اجرا می‌شود، بنابراین هستهٔ سیستم عامل یا برنامه‌های دیگر در صورتی که بخواهند در حالت دیگری به جز حالت واقعی اجرا شوند، باید به صورت صریح به آن حالت منتقل شوند. جابجایی بین حالت‌ها با تغییر دادن برخی بیت‌های مشخص از ثبات‌های کنترل‌کننده ی پردازنده، بعد از یک سری آماده‌سازی‌ها، انجام می‌شود و ممکن است تعدادی تنظیمات اضافی نیز بعد از جابجایی مورد نیاز باشد.
به‌طور کلی، ویژگی‌های مجموعه دستورالعمل‌های مدرن x86 عبارتند از:
طول متغیر و همسایگی مستقل (کدگذاری شده به عنوان Endian کمی، همان‌طور که تمام داده‌ها در معماری x86)
معماری x86 دارای پشتیبانی سخت‌افزاری برای اجرای مکانیسم‌های مربوط به پشته است. دستورالعمل‌هایی مانند codice_8، codice_9، codice_10 و codice_11 با کمک پشته اجرا می‌شوند و برای پاس دادن پارامترها، اختصاص دادن فضا به داده‌های محلی و ذخیره و بازیابی نقاط بازگشت دستور call استفاده می‌شود. دستورالعمل codice_12 وقتی به کار می‌رود که تابع صدا زده شده مسئولیت احیای فضای اشغال شدهٔ پشته توسط پارامترها را به عهده داشته باشد.
برای تنظیم یک کادر پشته جهت نگهداری داده‌های محلی یک تابع بازگشتی چندین راه وجود دارد؛ اولین راه استفاده از دستورالعمل codice_13 (این دستور همراه با ۸۰۳۸۶ معرفی شد) است که می‌تواند سریعتر از بسیاری دستورالعمل‌های دیگر باشد (مانند codice_14 ؛ codice_15 ؛ codice_16). هرچند سریع تر بودن یا آهسته‌تر بودن این روش علاوه بر نوع پیاده‌سازی پردازندهٔ x86، وابسته به قراردادهای فراخوانی مربوط به کامپایلر، برنامه‌نویس یا کد خاص یک برنامه نیز خواهد بود.
طیف گستردهٔ حالت‌های آدرس دهی (از جمله "بی واسطه" و "پایه + افست") برای دستورالعمل‌هایی مانند codice_8 و codice_9، استفادهٔ مستقیم از پشته را برای داده‌هایی مانند عدد صحیح، ممیز شناور و آدرس ساده‌تر می‌کند، همچنین، نگه داشتن مشخصات و مکانیزم ABI نسبت به برخی معماری‌های RISC ساده‌تر خواهد بود.
اسمبلی x86 دارای عملیات‌های ریاضی استاندارد، مانند: codice_19، codice_20، codice_21، codice_22 عملگرهای منطقی مانندcodice_23 codice_24: codice_25، codice_26 ؛ عملیات شیفت ریاضی و منطقی: codice_27 / codice_28، codice_29 / codice_30 ؛ چرخش همراه با رقم نقلی و چرخش بدون رقم نقلی مانند: codice_31 / codice_32 codice_33 / codice_34، مکمل دستورالعمل‌های محاسبهٔ BCD , codice_35، codice_36، codice_37 و سایر دستورالعمل‌ها است.
زبان اسمبلی x86 شامل دستورالعمل‌هایی برای یک واحد ممیز شناور مبتنی بر پشته (FPU) است. FPU در سری پردازنده‌های ۸۰۸۶ تا ۸۰۳۸۶، یک پردازندهٔ جداگانهٔ کمکی اختیاری بود، در سری پردازنده‌های ۸۰۴۸۶ یک ویژگی اختیاری روی تراشه بود و از سری ۸۰۴۸۶ به بعد، یک ویژگی استاندارد در هر پردازنده Intel x86 است، که از پنتیوم آغاز شد. دستورالعمل‌های FPU شامل جمع، تفریق، نفی، ضرب، تقسیم، باقی مانده، ریشه‌های مربع، کوتاه سازی عدد صحیح، کوتاه سازی کسر و مقیاس کردن با توان دو است. این دستوالعمل‌ها همچنین شامل دستورالعمل‌های تبدیل هستند که می‌توانند یک مقدار را از حافظه در هر یک از فرمت‌های: دهدهی کدگذاری شده به صورت دودویی، صحیح ۳۲ بیتی، صحیح ۶۴ بیتی، ممیز شناور ۳۲ بیتی، ممیز شناور ۶۴ بیتی یا ممیز شناور ۸۰ بیتی (در هنگام بارگیری، مقدار مورد نظر به حالت ممیز شناور در حال حاضر استفاده شده تبدیل می‌شود) بارگذاری یا در حافظه ذخیره کنند. x86 همچنین شامل تعدادی از توابع غیرجبری، از جمله سینوس، کسینوس، تانژانت، آرکتانژانت، به توان رساندن با پایه ۲ و لگاریتم در مبنای‌های ۲، ۱۰، یا e، می‌شود.
دستورالعمل‌هایی که مربوط به ثبات‌های پشته هستند معمولاً فرمتی به شکلcodice_38 یا codice_39 دارند که codice_40 معادل codice_41 می‌باشد و codice_42 یکی از ۸ رکورد پشته (codice_41، codice_44، …، codice_45). مانند دستورالعمل‌های مربوط به اعداد صحیح، اولین عملوند هم اولین عملوند مبدأ است و هم عملوند مقصد. codice_46 و codice_47 باید قبل از انجام تفریق یا تقسیم، اولی مبادله اپراتورهای منبع را انتخاب کنند. دستورالعمل اضافه، تفریق، ضرب، تقسیم، ذخیره و مقایسه شامل دستورالعمل‌هایی است که بعد از عملیاتشان پشته بالای پشته می‌شوند؛ بنابراین، به عنوان مثال، codice_48 محاسبه codice_49، سپس codice_41 از بالای پشته حذف می‌کند، بنابراین نتیجه در codice_44 بالای پشته در codice_41 .
CPUهای مدرن x86 شامل دستورالعمل‌های SIMD هستند که عمدتاً عملیات مشابه را به‌طور موازی در بسیاری از مقادیر کد گذاری شده در ثبت یک SIMD گسترده انجام می‌دهند. تکنولوژی‌های مختلف آموزش از عملیات‌های مختلف در مجموعه‌های ثبت نام مختلف پشتیبانی می‌کنند اما در کل کامل (از MMX به SSE4.2) شامل محاسبات عمومی در ریاضی عدد صحیح یا شناور (اضافه کردن، تفریق، ضرب، تغییر، حداقل، حداکثر سازی، مقایسه، تقسیم یا مربع ریشه) بنابراین برای مثال، codice_53 انجام ۴ موازی ۱۶ بیتی (نشان داده شده codice_54) عدد صحیح می‌افزاید (نشان داده شده codice_55) از codice_56 ارزش به codice_57 و در نتیجه در ذخیره codice_56 . جریان SIMD Extensions یا SSE همچنین شامل یک حالت نقطه شناور است که در آن فقط تنها اولین مقدار از registers در واقع اصلاح شده‌است (گسترش در SSE2). برخی از دستورالعمل‌های غیرمعمول دیگر شامل مجموع اختلاف‌های مطلق (استفاده می‌شود برای برآورد حرکت در فشرده سازی ویدئو، مانند در MPEG انجام می‌شود) و دستورالعمل تجمع ۱۶ بیتی (مفید برای نرم‌افزار مبتنی بر ترکیب آلفا و فیلتر دیجیتال). SSE (از SSE3) و 3DNow! برنامه‌های افزودنی شامل دستورالعمل اضافه کردن و تفریق برای درمان مقادیر ذره شناور زوج مانند اعداد پیچیده‌است.
این مجموعه دستورالعمل‌ها همچنین شامل دستورالعمل‌های چند کلمه ای ثابت متعدد برای شیفت دادن، قرار دادن و استخراج مقادیر درون ثبات‌ها هستند. علاوه بر این دستورالعمل‌هایی برای انتقال داده بین ثبات‌های عدد صحیح و ثبات‌های XMM (مورد استفاده در SSE) FPU (استفاده شده در MMX)
پردازندهٔ x86 همچنین شامل حالت‌های پیچیدهٔ آدرس دهی حافظه با یک افست بی واسطه، یک ثبات، یک ثبات با یک افست، یک ثبات مقیاس پذیر با افست یا بدون افست، و یک ثبات با یک افست اختیاری و یک ثبات مقیاس پذیر؛ بنابراین، برای مثال، می‌توان codice_59 را به عنوان یک دستور واحد که ۳۲ بیت داده را از آدرس محاسبه شده با افست codice_60 از codice_61 بارگذاری می‌کند و در ثبات eax ذخیره می‌کند. به‌طور کلی، پردازنده‌های x86 می‌توانند بارگذاری کرده و استفاده از حافظه سازگار با اندازه هر یک از ثبت نام آن عمل می‌کند. (دستورالعمل SIMD همچنین شامل دستورالعمل نیمه بار است)
مجموعه آموزشی x86 شامل بار رشته، فروشگاه، حرکت، اسکن و مقایسه دستورالعمل (codice_62، codice_63، codice_64، codice_65 و codice_66) که انجام هر عملیات به یک اندازه مشخص (codice_67 برای بایت ۸ بیتی، codice_54 برای کلمه ۱۶ بیتی، codice_69 برای کلمهٔ ۳۲ بیتی دو برابر) پس از آن افزایش / کم می (بسته به DF، پرچم جهت) آدرس ثبت نام ضمنی (codice_70 برای codice_62، codice_72 برای codice_63 و codice_65، و هر دو برای codice_64 و codice_66). برای بار، فروشگاه و عملیات اسکن، ضمنی هدف / منبع / مقایسه ثبت نام در است codice_77، codice_78 یا codice_79 ثبت نام (بسته به اندازه). ثبات بخش ضمنی استفاده می‌شود codice_61 برای codice_70 و codice_82 برای codice_72 . ثبت نام codice_84 یا codice_85 به عنوان یک شمارنده کاهش می‌یابد و عملیات زمانی که شمارنده برابر صفر می‌شود یا (برای اسکن و مقایسه‌ها) هنگامی که نابرابری شناسایی می‌شود، متوقف می‌شود.
پشته با اشاره گر پشته ضمنی کاهش (افزایش) و افزایش (پاپ) قرار می‌گیرد. در حالت ۱۶ بیتی، این نشانگر پشته ضمنی به عنوان SS: [SP] خطاب شده‌است، در حالت ۳۲ بیت SS است: [ESP]، و در حالت ۶۴ بیتی [RSP] است. اشاره گر پشته عموماً به آخرین مقدار ذخیره شده اشاره می‌کند، با این فرض که اندازه آن با حالت عملیاتی پردازنده (یعنی ۱۶، ۳۲ یا ۶۴ بیت) مطابقت دارد با عرض پیش فرض codice_8 / codice_9 / codice_10 / codice_11 دستورالعمل. همچنین دستورالعمل‌ها codice_13 و codice_91 که ذخیره و حذف داده‌ها از بالای پشته در هنگام تنظیم یک اشاره گر قاب پشته در codice_92 / codice_1 / codice_2 . با این حال، تنظیم مستقیم، یا جمع و تفریق به ثبت codice_95 / codice_96 / codice_97 نیز پشتیبانی می‌شود، بنابراین دستورالعمل codice_13 / codice_91 به‌طور کلی غیر ضروری است.
این کد در آغاز یک تابع نوشته می‌شود:
فرض بر این است که ارزش برای یک بار یا فروشگاه SIMD در موقعیت‌های مجاور برای ثبت SIMD بسته‌بندی می‌شود و آن‌ها را در ترتیبی از ترتیب کمی محدود می‌کند. بعضی از دستورالعمل‌های بارگذاری و ذخیره SSE به درستی عمل می‌کنند تا هماهنگ سازی ۱۶ بایت انجام شود. دستورالعمل‌های SIMD همچنین شامل دستورالعمل پیشفرشی هستند که بار را انجام می‌دهند اما هیچ ثبتی را هدف قرار نمی‌دهند، که برای بارگیری کش استفاده می‌شود. دستورالعمل‌های SSE همچنین شامل دستورالعمل‌های فروشگاه غیر زمانی هستند که فروشگاه‌ها را مستقیماً به حافظه بدون انجام کش کش اختصاص می‌دهند اگر مقصد قبلاً ذخیره نگردد (در غیر این صورت مانند یک فروشگاه منظم رفتار خواهد کرد)
بیشترین دستورالعمل عدد صحیح عمومی و شناور (اما بدون SIMD) می‌تواند از یک پارامتر به عنوان یک منبع پیچیده به عنوان پارامتر منبع دوم استفاده کند. دستورالعمل‌های عدد صحیح نیز می‌توانند یک پارامتر حافظه را به عنوان یک عملگر مقصد اعمال کنند.
مأموریت x86 دارای عملیات پرش بدون قید و شرط، codice_104 که می‌تواند یک آدرس فوری، یک ثبت یا یک آدرس غیرمستقیم به عنوان یک پارامتر (توجه داشته باشید که اکثر پردازنده‌های RISC فقط از یک پرونده لینک یا یک جابجایی فوری کوتاه برای پریدن حمایت می‌کنند).
همچنین پشتیبانی می‌شود چند جهش مشروط، از جمله codice_105 (پرش به صفر)، codice_106 (پرش در غیر صفر)، codice_107 (پرش در بزرگتر از، امضا)، codice_108 (پرش در کمتر از، امضا)، codice_109 (پرش در بالا / بزرگتر از، بدون علامت)، codice_110 (پرش در زیر / کمتر از، unsigned). این عملیات مشروط بر اساس بیت مشخص در ثبت (E) FLAGS بنا شده‌است. بسیاری از عملیات ریاضی و منطقی، بسته به نتیجه آنها، این پرچم‌ها را مشخص یا تکمیل می‌کنند. مقایسه مقادیر codice_111 (مقایسه) و دستورالعمل‌های codice_112، پرچم‌ها را به گونه ای تنظیم می‌کند که به ترتیب، آن‌ها را به‌طور جداگانه یا عملیات bitwise AND انجام داده‌اند، بدون تغییر مقادیر عملان. همچنین دستورالعمل‌هایی مانند codice_113 (پرچم حمل روشن) و codice_114 (پرچم تکمیل حمل) وجود دارد که به‌طور مستقیم بر روی پرچم‌ها کار می‌کند. شناور مقایسه نقاط از طریق انجام codice_115 یا codice_116 دستورالعمل که در نهایت باید به پرچم عدد صحیح تبدیل می‌شود.
هر عمل پرش به سه شکل متفاوت است: بسته به اندازه اپنج. پرش "کوتاه" از عملیات امضا شده ۸ بیتی استفاده می‌کند که از دستورالعمل فعلی جبران می‌شود. پرش "نزدیک" شبیه یک پرش کوتاه است اما با استفاده از عملگر ۱۶ بیتی امضا شده (در حالت واقعی یا محافظت شده) یا عمل ۳۲ بیتی امضا شده (فقط در حالت محافظت شده ۳۲ بیتی). پرش به "مراتب" یکی است که از پایه کامل بخش استفاده می‌کند: مقدار افست به عنوان آدرس مطلق. اشکال غیرمستقیم و نمایه شده از هر کدام نیز وجود دارد.
علاوه بر عملیات پرش ساده، codice_10 (call subroutine) و codice_11 (return from subroutine) دستورالعمل‌ها هستند. قبل از انتقال کنترل به زیر فرعی، codice_10 را فشار دهید آدرس offset بخش دستورالعمل زیر codice_10 به پشته؛ codice_11 این مقدار را از پشته باز می‌کند و به آن می‌پیوندد، به‌طور مؤثر بازگشت جریان کنترل به آن قسمت از برنامه. در مورد codice_122، پایه بخش تحت فشار قرار می‌گیرد؛ codice_123 می‌آید افست و سپس پایه بخش به بازگشت.
همچنین دو دستورالعمل مشابه وجود دارد: codice_124 (interrupt)، که موجب صرفه جویی در مقدار فعلی (E) FLAGS ثبت شده در پشته می‌شود، سپس یک codice_122 انجام می‌دهد، به جز آن که به جای آدرس، از یک "بردار وقفه"، یک شاخص به یک جدول استفاده می‌کند از آدرس‌های پردازش وقفه. به‌طور معمول، پردازنده وقفه موجب صرفه جویی در تمام سایر پردازنده‌های ثبت شده مورد استفاده می‌شود، مگر اینکه آن‌ها برای بازگشت نتیجه عملیات به برنامه تماس (در نرم‌افزار به نام وقفه‌ها) مورد استفاده قرار گیرد. بازگشت تطبیقی از دستورالعمل وقفه codice_126، که پس از بازگشت، پرچم‌ها را بازیابی می‌کند. "قطعهای نرم" از نوع توصیف شده در بالا بعضی از سیستم عامل‌ها برای تماس‌های سیستم استفاده می‌شود و همچنین می‌تواند در اشکال زدایی مدرسان وقفه‌های سخت استفاده شود. "وقفه‌های سخت" باعث وقایع سخت‌افزاری خارجی می‌شوند و باید تمام مقادیر ثبت را حفظ کنند به عنوان وضعیت برنامه فعلی اجرای ناشناخته است. در حالت حفاظت شده، وقفه ممکن است توسط سیستم عامل برای راه اندازی یک سوئیچ کار، که به‌طور خودکار تمام ثبت نام از کار فعال را ذخیره کنید.
از وقفهٔ 21h برای نمایش خروجی استفاده می‌شود، مثال‌های دیگر از printf برای نمایش خروجی استفاده می‌کنند .  .model small .stack 100h
.data msg db 'Hello world!$'
.code start: mov ah, 09h ; Display the message lea dx, msg int 21h mov ax, 4C00h ; Terminate the executable int 21h
end start
.386 .model small,c .stack 1000h
.data msg db "Hello world!",0
.code includelib libcmt.lib includelib libvcruntime.lib includelib libucrt.lib includelib legacy_stdio_definitions.lib
extrn printf:near extrn exit:near
public main main proc main endp
end
%define RVA(x) (x-0x00400000) section .text push dword hello call dword [printf] push byte +0 call dword [exit] ret
section .data hello db "Hello world!"
section .idata dd RVA(msvcrt_LookupTable) dd -1 dd 0 dd RVA(msvcrt_string) dd RVA(msvcrt_imports) times 5 dd 0 ; جدول را تمام می‌کند
msvcrt_string dd "msvcrt.dll", 0 msvcrt_LookupTable: dd RVA(msvcrt_printf) dd RVA(msvcrt_exit) dd 0
msvcrt_imports: printf dd RVA(msvcrt_printf) exit dd RVA(msvcrt_exit) dd 0
msvcrt_printf: dw 1 dw "printf", 0 msvcrt_exit: dw 2 dw "exit", 0 dd 0
section .data ; section for initialized data str: db 'Hello world!', 0Ah ; message string with new-line char at the end (10 decimal) str_len: equ $ - str ; calcs length of string (bytes) by subtracting the str's start address
section .text ; this is the code section global _start ; _start is the entry point and needs global scope to be 'seen' by the _start: ; definition of _start procedure begins here mov eax, 4 ; specify the sys_write function code (from OS vector table) mov ebx, 1 ; specify file descriptor stdout --in gnu/linux, everything's treated as a file, mov ecx, str ; move start _address_ of string message to ecx register mov edx, str_len ; move length of message (in bytes) int 80h ; interrupt kernel to perform the system call we just set up - mov eax, 1 ; specify sys_exit function code (from OS vector table) mov ebx, 0 ; specify return code for OS (zero tells OS everything went fine) int 80h ; interrupt kernel to perform system call (to exit)
global main ;main must be defined as it being compiled against the C-Standard Library  extern printf ;declares use of external symbol as printf is declared in a different object-module.
segment .data ;section for initialized data string db 'Hello world!', 0Ah, 0h ;message string with new-line char (10 decimal) and the NULL terminator
segment .text main:BITS 64
SECTION .data
Hello: db "Hello world!",10 len_Hello: equ $-Hello
SECTION .text
global _start
_start: mov rax,1 ; write syscall (x86_64) mov rdi,1 ; fd = stdout mov rsi,Hello ; *buf = Hello mov rdx,len_Hello ; count = len_Hello syscall
mov rax,60 ; exit syscall (x86_64) mov rdi,0 ; status = 0 (exit normally) syscall پرچم‌ها در معماری x86 برای عمل مقایسه بسیار مورد استفاده قرار می‌گیرند. هنگام مقایسهٔ بین دو داده، CPU، مقدار پرچم یا پرچم مربوطه را تنظیم می‌کند. با توجه به مقادیر قرار گرفته در پرچم‌ها، دستورالعمل‌های پرش شرطی انجام می‌شوند و برنامه به کدی که باید انجام شود پرش می‌کند، به عنوان مثال:  cmp eax, ebx jne do_something do_something:  پرچم‌ها نیز در معماری x86 برای روشن و خاموش کردن ویژگی‌های خاص یا حالت‌های اجرا استفاده می‌شود. برای مثال، برای غیرفعال کردن همه وقفه‌های ماسک، می‌توانید از دستور زیر استفاده کنید:  cli
اشارهگر دستور codice_135 در حالت ۱۶ بیت نامیده می‌شود، در حالت ۳۲ بیتی codice_136 در حالت ۶۴ بیتی codice_137 شود. ثبت نام اشارهگر دستور اشاره به آدرس حافظه است که پردازنده بعدی تلاش برای اجرا؛ آن را نمی‌توان به صورت مستقیم در حالت ۱۶ بیتی یا ۳۲ بیتی مشاهده کرد، اما یک توالی مانند زیر می‌توان برای قرار دادن آدرس codice_138 به codice_79 :  call next_line next_line: pop eax
نوشتن به اشاره گر دستورالعمل ساده است - دستور codice_141 دستورالعمل دستورالعمل را به آدرس مقصد هدایت می‌کند، به عنوان مثال، یک توالی مانند زیر، محتویات codice_79 را به codice_136 :  jmp eax