ثبات ها در زبان اسمبلی
اکثر عملیاتی که توسط پردازنده ها انجام می شود، مربوط به پردازش داده ها است. این داده ها را می توان در حافظه ذخیره کرد تا از این طریق بتوان به آن ها دسترسی داشت. با این حال خواندن و ذخیره داده ها در حافظه باعث کاهش کارایی پردازنده می شود، زیر فرآیندهای پیچیده ارسال درخواست داده درون Control Bus و واحد ذخیره سازی حافظه و سپس گرفتن داده ها از طریق همان کانال باعث کاهش سرعت پردازنده می شود.
به منظور افزایش سرعت عملکرد پردازنده، از برخی مکان های ذخیره سازی داخلی به نام ثبات (Register) استفاده می شود. ثبات ها المان های داده را به منظور پردازش بدون نیاز به دسترسی به حافظه اصلی، ذخیره می کنند. تعداد ثبات ها در پردازنده ها محدود است.
ثبات پردازنده
معماری IA-32، شامل 10 پردازنده 32 بیتی و 6 پردازنده 16 بیتی می باشد.
ثبات ها به سه دسته زیر تقسیم می شوند:
- ثبات های عمومی (General Registers)
- ثبات های کنترلی (Control Registers)
- ثبات های مربوط به سگمنت (Segment Registers)
ثبات های عمومی خود نیز به سه دسته زیر تقسیم می شوند:
- ثبات های داده Data Registers))
- ثبات های اشاره گر (Pointer Registers)
- ثبات های ایندکس (Index Registers)
ثبات های داده (Data Registers)
چهار ثبات داده ای 32 بیتی برای اعمال محاسباتی، منطقی و غیره مورد استفاده قرار می گیرند. این ثبات ها را به سه روش زیر می توان استفاده کرد:
- به عنوان یک ثبات 32 بیتی کامل EAX , EBX, ECX, EDX.
- بخش کم ارزش به عنوان ثبات های 16 بیتی AX, BX, CX, DX.
- بخش کم ارزش و پر ارزش هر یک به عنوان ثبات های 16 بیتی.
ثبات AX به عنوان انباشتگر اصلی (primary accumulator) برای I/O و اکثر دستورالعمل های محاسباتی مورد استفاده قرار می گیرد. برای مثال در عملیات ضرب بر اساس اندازه عملوند، یک عملوند در ثبات EAX یا AX و یا AL ذخیره می شود.
ثبات BX به عنوان ثبات پایه (Base Register) شناخته می شود و در آدرسی دهی فهرستی مورد استفاده قرار می گیرد.
ثبات CX به عنوان ثبات شمارنده (Count Register) شناخته می شود، دو ثبات ECX و CX تعداد تکرار حلقه را در عملیات های تکراری ذخیره می کنند.
ثبات DX به عنوان ثبات داده (Data Register) شناخته می شود، این ثبات در عملیات I/O و همچنین به همراه ثبات AX برای عملیات ضرب و تقسیم مقادیر بزرگ مورد استفاده قرار می گیرد.
ثبات های اشاره گر (Pointer Registers)
ثبات های اشاره گر، ثبات های 32 بیتی ESP، EIP و EBP و 16 بیتی SP، IP و BP هستند. در زیر سه دسته ثبات اشاره گر را مشاهده می کنید:
- اشاره گر دستورالعمل (Instruction Pointer) : ثبات 16 بیتیIP آدرس offset دستورالعمل بعدی رو که پردازنده باید اجرا کند را در خود ذخیره می کند. اجتماع IP با ثبات CS به عنوان CS:IP آدرس کامل دستورالعمل فعلی را در سگمنت کد به ما می دهد.
- اشاره گر پشته (Stack Pointer) : ثبات 16 بیتیSP مقدار offset موجود در پشته برنامه را فراهم می کند. اجتماع SP و SS باهم به شکل SS:SP به مکان فعلی داده یا آدرس در پشته برنامه اشاره می کند.
- اشاره گر پایه (Base Pointer) : این ثبات 16 بیتی به ارجاع دهی متغیر های پارامتری که به زیر مجموعه ها پاس داده می شوند، کمک می کند. آدرس ثبات SS با offset در BP ترکیب می شود و مکان پارامتر را به ما می دهد. BP می تواند با DI و SI به عنوان ثبات های پایه برای آدرس دهی های خاص استفاده شود.
ثبات های ایندکس (Index Registers)
این ثبات های 32 بیتی، ESI و EDI و 16 بیتی SI و DI برای آدرس دهی شاخص دار و بعضی مواقع هم برای اعمال جمع و تفریق مورد استفاده قرار می گیرند و بر دو نوع تقسیم می شوند:
- Source Index (SI) : در عملیات بر روی رشته ها به عنوان شاخص مبدا مورد استفاده قرار می گیرد.
- Destination Index (DI) : در عملیات بر روی رشته ها به عنوان شاخص مقصد مورد استفاده قرار می گیرد.
ثبات های کنترلی (Control Registers)
ثبات اشاره گر دستورالعمل 32 بیتی و ثبات های flag 32 بیتی با هم ترکیب می شوند و ثبات های کنترلی را می سازند. بسیاری از دستورالعمل ها (مانند مقایسه ها، محاسبات ریاضی، تغییر وضعیت flag ها و برخی از دستورالعمل های شرطی) این flag ها را به منظور انتقال جریان به سایر مکان ها، بررسی می کنند.
Flag های بیتی رایج را در زیر مشاهده می کنید:
- Overflow Flag OF : برای یک بیت پر ارزش سرریز را مشخص می کند.
- Direction Flag DF : نوع مقایسه رشته ها را مشخص می کند. اگر صفر باشد مقایسه از چپ شروع می شود و اگر یک باشد از راست شروع می شود.
- Interrupt Flag IF : مشخص می کند که آیا وقفه های خارجی مثل ورودی صفحه کلید و غیره باید نادیده گرفته شود یا پردازش شود. هنگامی که صفر باشد، وقفه خارجی را غیرفعال می کند و هنگامی که یک باشد، وقفه خارجی را فعال می کند.
- Trap Flag TF : اجازه میده عملیات پردازنده پلکانی پیش برود. برای اشکال زدایی (debug) کردن برنامه ها مورد استفاده قرار می گیرد.
- Sign Flag SF : علامت جواب بدست آمده از علیات محاسباتی را مشخص می کند. اگر یک باشد یعنی عدد منفی است.
- Zero Flag ZF : نتیجه حاصله از عملیات ریاضی یا مقایسه ای را مشخص می کند. اگر نتیجه غیر صفر باشد، flag با مقدار 0 تنظیم می شود و اگر نتیجه صفر باشد، flag با مقدار 1 تنظیم خواهد شد.
- Auxiliary Carry Flag AF : شامل انتقال از بیت 3 به 4 پس از عملیات محاسباتی می باشد. برای محاسبات تخصصی مورد استفاده قرار می گیرد. AF زمانی تنظیم می شود که یک عملیات ریاضی 1 بایتی، باعث انتقال از بیت 3 به بیت 4 شود.
- Parity Flag PF : بر اساس تعداد 1 های موجود در نتیجه حاصله از عملیات تنظیم می شود. اگر تعداد زوج باشد، 0 و اگر فرد باشد 1 خواهد شد.
- Carry Flag CF : شامل مقدار نقلی از بیت پر ارزش تر می باشد.
جدول زیر مکان flag ها را برای flag های 16 بیتی نمایش می دهد:
Flag | O | D | I | T | S | Z | A | P | C | |||||||
شماره بیت | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
ثبات های سگمنت (Segment Registers)
سگمنت ناحیه ای از حافظه است که آدرس شروع آن بر 16 قابل قسمت است و از مرز پاراگراف شروع می شود. اندازه سگمنت می تواند تا 64 کیلو بایت باشد. برنامه ها اسمبلی چهار نوع سگمنت دارند که در زیر مشاهده می کنید:
- سگمنت داده (Data segment) : در این بخش داده ها و ناحیه کاری قرار می گیرد.
- سگمنت کد (Code segment) : دستورات زبان ماشین در این بخش قرار می گیرند.
- سگمنت پشته (Stack segment) : در این بخش آدرس بازگشت از زیر برنامه ها قرار می گیرد.
- سگمنت اضافه (Extra segment) : این سگمنت برای انجام عملیات بر روی رشته ها مورد استفاده قرار می گیرد.
مثال
برای درک بهتر استفاده از ثبات ها در برنامه نویسی اسمبلی، به برنامه ساده زیر توجه کنید. این برنامه 9 ستاره را بر روی صفحه نمایش همراه با یک پیام ساده نمایش می دهد:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | section .text global _start ;must be declared for linker (gcc) _start: ;tell linker entry point mov edx,len ;message length mov ecx,msg ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov edx,9 ;message length mov ecx,s2 ;message to write mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax,1 ;system call number (sys_exit) int 0x80 ;call kernel section .data msg db 'Displaying 9 stars',0xa ;a message len equ $ - msg ;length of message s2 times 9 db '*' |
زمانی که کد بالا توسط کامپایلر اسمبلی و اجرا شود، نتیجه زیر را تولید خواهد کرد:
1 2 | Displaying 9 stars ********* |
هیچ نظری ثبت نشده است