همراهان عزیز وب سایت آموزشی پی وی لرن وقتتون بخیر و شادی، با آموزش زبان برنامه نویسی اسمبلی (Assembly) در خدمتتون خواهیم بود. در این بخش از آموزش، مبحث ساختار شرطی در زبان اسمبلی (Assembly) خواهیم داشت و به بررسی مواردی چون پرش شرطی (Conditional Jump) و غیر شرطی و دستورالعمل CMP می پردازیم. با ادامه ی آموزش ها همراه باشید.
اجرای شروط به زبان اسمبلی توسط چندین دستورالعمل حلقه و branching (پرش) انجام می شود. این دستورالعمل ها می توانند جریان کنترل را در یک برنامه تغییر دهند. اجرای شروط در دو سناریو مشاهده می شود.
ساختار شرطی در زبان اسمبلی (Assembly) را در جدولی داریم.
ردیف | ساختار شرطی |
---|---|
۱ | پرش غير شرطي (unconditional Jump) توسط دستورالعمل JMP انجام می شود. اجرای شروط غالباً شامل انتقال كنترل به آدرس دستورالعملی است كه از دستورالعمل اجرای كنونی پیروی نمی كند. انتقال کنترل ممکن است رو به جلو باشد ، برای اجرای مجموعه جدیدی از دستورالعمل یا قبلی، اجرای دوباره همان مراحل.
|
۲ | پرش شرطي (Conditional jump) بسته به شرایط ، توسط مجموعه ای از دستورالعمل های پرش <j <condition انجام می شود. دستورالعمل های شرطی، کنترل را با شکستن جریان پی در پی انتقال می دهند و آن ها را با تغییر مقدار افست در IP انجام می دهند. |
بگذارید قبل از بحث در مورد دستورالعمل های شرطی ، دستورالعمل CMP را مورد بحث قرار دهیم.
دستورالعمل CMP دو عملوند را مقایسه می کند. عموماً در اجرای شرطی مورد استفاده قرار می گیرد. این دستورالعمل اساساً برای مقایسه این که آیا عملوند برابر است یا خیر ، یک عملوند را از دیگری کم می کند. باعث اختلال در عملوند های منبع یا مقصد نمی شود. از آن به همراه دستورالعمل پرش شرطی برای تصمیم گیری استفاده می شود.
1 | CMP destination, source |
CMP دو فیلد داده عددی را مقایسه می کند. عملوند مقصد می تواند در ثبات یا در حافظه باشد. عملوند منبع می تواند یک داده ثابت (فوری)، ثبات یا حافظه باشد.
1 2 3 4 5 | CMP DX, 00 ; Compare the DX value with zero JE L7 ; If yes, then jump to label L7 . . L7: ... |
CMP بیش تر برای مقایسه این که آیا یک مقدار شمارنده به تعداد دفعاتی که یک حلقه برای اجرا نیاز دارد رسیده است، استفاده می شود. شرایط معمولی زیر را در نظر بگیرید.
1 2 3 | INC EDX CMP EDX, 10 ; Compares whether the counter has reached 10 JLE LP1 ; If it is less than or equal to 10, then jump to LP1 |
همان طور که قبلاً ذکر شد ، این کار با دستور JMP انجام می شود. اجرای شروط غالباً شامل انتقال كنترل به آدرس دستورالعملی است كه از دستورالعمل اجرای كنونی پیروی نمی كند. انتقال کنترل ممکن است رو به جلو باشد ، برای اجرای مجموعه جدیدی از دستورالعمل یا قبلی، اجرای دوباره همان مراحل.
دستورالعمل JMP نام لیبلی را در اختیار شما قرار می دهد که سریعاً جریان کنترل انتقال یابد. سینتکس دستورالعمل JMP به شکل زیر است.
1 | JMP label |
قطعه کد زیر دستورالعمل JMP را نشان می دهد.
1 2 3 4 5 6 7 8 | MOV AX, 00 ; Initializing AX to 0 MOV BX, 00 ; Initializing BX to 0 MOV CX, 01 ; Initializing CX to 1 L20: ADD AX, 01 ; Increment AX ADD BX, AX ; Add AX to BX SHL CX, 1 ; shift left CX, this in turn doubles the CX value JMP L20 ; repeats the statements |
اگر برخی از شروط مشخص در پرش شرطی براورده شود ، جریان کنترل به دستورالعمل هدف منتقل می شود. بسته به شرایط و داده ها دستورالعمل های پرش شرطی متعددی وجود دارد.
در زیر دستورالعمل های پرش شرطی مورد استفاده در داده های علامت دار مورد استفاده برای عملیات حسابی آمده است.
دستورالعمل | شرح | Flag ها |
---|---|---|
JE/JZ | پرش در صورتی که مساوی است یا پرش در صورتی که صفر است. | ZF |
JNE/JNZ | پرش در صورتی که مساوی نیست یا پرش در صورتی که صفر نیست. | ZF |
JG/JNLE | پرش در صورتی که پایین و مساوی نیست یا پرش در صورتی که بزرگ تر است. | OF, SF, ZF |
JGE/JNL | پرش در صورتی که پایین نیست یا پرش در صورتی که بزرگ تر یا مساوی است. | OF, SF |
JL/JNGE | پرش در صورتی که پایین است یا پرش در صورتی که بزرگ تر یا مساوی نیست. | OF, SF |
JLE/JNG | پرش در صورتی که پایین و مساوی است یا پرش در صورتی که بزرگ تر نیست. | OF, SF, ZF |
در زیر دستورالعمل های پرش شرطی مورد استفاده در داده های بدون علامت استفاده شده برای عملیات منطقی آورده شده است.
دستورالعمل | شرح | Flag ها |
---|---|---|
JE/JZ | پرش در صورت مساوی بودن یا پرش در صورت صفر بودن | ZF |
JNE/JNZ | پرش در صورت مساوی نبودن یا پرش در صورت صفر نبودن | ZF |
JA/JNBE | پرش در صورتی که بالاتر است یا پرش در صورتی که پایین یا مساوی نیست. | CF, ZF |
JAE/JNB | پرش در صورتی که پایین نیست یا پرش در صورتی که بالاتر یا مساوی است | CF |
JB/JNAE | پرش در صورتی که پایین است یا پرش در صورتی که بالاتر یا مساوی نیست. | CF |
JBE/JNA | پرش در صورتی که بالا نیست یا پرش در صورتی که پایین یا مساوی است. | AF, CF |
دستورالعمل های پرش شرطی زیر موارد ویژه ای دارند و مقدار flag ها را بررسی می کنند.
دستورالعمل | شرح | Flag ها |
---|---|---|
JXCZ | Jump if CX is Zero | none |
JC | پرش در صورتی که رقم نقلی وجود دارد. | CF |
JNC | پرش در صورتی که رقم نقلی وجود ندارد. | CF |
JO | پرش در صورتی که سرريز وجود دارد. | OF |
JNO | پرش در صورتی که سرريز وجود ندارد. | OF |
JP/JPE | پرش در صورتی که پريتی زوج است یا پرش در صورتی که پريتی است. | PF |
JNP/JPO | پرش در صورتی که پريتی فرد است یا پرش در صورتی که پريتی نیست. | PF |
JS | پرش در صورتی که مثبت است. | SF |
JNS | پرش در صورتی که منفی است. | SF |
سینتکس مجموعه دستورالعمل های J <condition> :
1 2 3 4 5 6 7 8 | CMP AL, BL JE EQUAL CMP AL, BH JE EQUAL CMP AL, CL JE EQUAL NON_EQUAL: ... EQUAL: ... |
در ادامه مثال دیگری را بررسی می کنیم.
برنامه زیر بزرگ ترین از سه متغیر را نشان می دهد. متغیرها متغیرهای دو رقمی هستند. سه متغیر num1 ، num2 و num3 به ترتیب دارای مقادیر ۴۷ ، ۲۲ و ۳۱ می باشند.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | Live Demo section .text global _start ;must be declared for using gcc _start: ;tell linker entry point mov ecx, [num1] cmp ecx, [num2] jg check_third_num mov ecx, [num2] check_third_num: cmp ecx, [num3] jg _exit mov ecx, [num3] _exit: mov [largest], ecx mov ecx,msg mov edx, len mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov ecx,largest mov edx, 2 mov ebx,1 ;file descriptor (stdout) mov eax,4 ;system call number (sys_write) int 0x80 ;call kernel mov eax, 1 int 80h section .data msg db "The largest digit is: ", 0xA,0xD len equ $- msg num1 dd '47' num2 dd '22' num3 dd '31' segment .bss largest resb 2 |
هنگامی که کد فوق کامپایل و اجرا می شود ، نتیجه زیر را ایجاد می کند.
1 2 | The largest digit is: 47 |
مبحث ساختار شرطی در زبان اسمبلی (Assembly) را در این بخش به پایان می رسونیم.
در مبحث ساختار شرطی در زبان اسمبلی (Assembly) به بررسی پرش شرطی (Conditional Jump) و غیر شرطی و دستورالعمل CMP پرداختیم. در جلسه ی آینده مبحث حلقه ها را مورد بررسی قرار خواهیم داد. با آموزش زبان اسمبلی (Assembly) از وب سایت آموزشی پی وی لرن همراه باشید.