
زبان اسمبلی یکی از پایینترین لایههای برنامهنویسی است و بهطور مستقیم با سختافزار سروکار دارد. هر دستور اسمبلی معمولاً معادل یک دستور ماشین است و مستقیماً توسط پردازنده اجرا میشود. در این مقاله، چند مورد از مهمترین و پرکاربردترین دستورات اسمبلی x86 را بررسی میکنیم و عملکرد هر کدام را توضیح میدهیم.
دستور MOV – انتقال داده
دستور MOV یکی از بنیادیترین و پرکاربردترین دستورات اسمبلی است. این دستور برای کپی کردن داده از یک مکان به مکان دیگر استفاده میشود.
مثال:
mov eax, ebx mov al, 10 mov [myValue], eax
مقدار موجود در EBX داخل رجیستر EAX کپی میشود.
عدد ۱۰ داخل رجیستر ۸ بیتی AL قرار میگیرد.
مقدار رجیستر EAX داخل آدرس myValue در حافظه نوشته میشود.
دستور ADD – جمع
این دستور جمع دو مقدار را انجام میدهد و نتیجه را در اپرند مقصد قرار میدهد.
مثال:
add eax, 5
مقدار ۵ به مقدار فعلی در رجیستر EAX اضافه میشود و نتیجه جایگزین مقدار EAX میشود.
دستور SUB – تفریق
مشابه ADD است، ولی عمل تفریق انجام میدهد.
مثال:
sub eax, 2
عدد ۲ از مقدار موجود در EAX کم میشود.
دستور INC و DEC – افزایش و کاهش
این دو دستور مقدار یک رجیستر یا حافظه را به اندازه ۱ افزایش یا کاهش میدهند.
مثال:
inc eax dec ebx
inc eax مقدار EAX را یک واحد زیاد میکند.
dec ebx مقدار EBX را یک واحد کم میکند.
دستور PUSH و POP – کار با استک
استک (Stack) بخش بسیار مهمی در اجرای برنامه است. دستورهای PUSH و POP برای ذخیره و بازیابی داده از استک استفاده میشوند.
مثال:
push eax pop ebx
مقدار EAX روی استک قرار میگیرد.
سپس POP مقدار بالای استک را داخل EBX برمیگرداند.
دستور CMP – مقایسه
مقایسهٔ دو مقدار با انجام یک عمل تفریق داخلی بدون ذخیره کردن نتیجه انجام میشود. این دستور معمولاً همراه با دستورات پرش استفاده میشود.
مثال:
cmp eax, 10
مقدار EAX با ۱۰ مقایسه میشود. نتیجه مقایسه فقط روی فلگها اثر میگذارد.
دستورهای پرش Jump (مانند JE ،JNE ،JG ،JL)
برای تغییر مسیر اجرای برنامه استفاده میشوند.
مثال:
cmp eax, 5 je equal_label
اگر مقدار EAX برابر با ۵ بود، پردازنده به برچسب equal_label میپرد.
دستور CALL – فراخوانی تابع
برای رفتن به یک تابع و ذخیرهٔ آدرس برگشت از آن استفاده میشود.
مثال:
call MyFunc
پردازنده به آدرس MyFunc میرود و پس از پایان تابع، با دستور RET به ادامه کار میپردازد.
دستور RET – بازگشت از تابع
از تابع جدا شده و به آدرس ذخیرهشده در استک برمیگردد.
مثال:
ret
آدرس برگشت از استک خارج شده و پردازنده به همان نقطه بازمیگردد.
دستور NOP – بدون عملیات
هیچ کاری انجام نمیدهد و فقط یک سیکل CPU مصرف میکند.
مثال:
nop
از NOP برای همترازسازی کد یا تاخیرهای جزئی استفاده میشود.
دستور MUL – ضرب بدون علامت
دستور MUL برای ضرب مقادیر بدون علامت (unsigned) استفاده میشود.
عملوند همیشه داخل رجیسترهای ویژه قرار میگیرد:
اگر عملوند ۸ بیتی باشد → ضرب: AL × operand → نتیجه در AX
اگر ۱۶ بیتی باشد → AX × operand → نتیجه در DX:AX
اگر ۳۲ بیتی باشد → EAX × operand → نتیجه در EDX:EAX
مثال:
mov al, 5 mov bl, 6 mul bl
5 × 6 انجام میشود و نتیجه یعنی 30 داخل رجیستر AX ذخیره میشود (در اینجا AH=0 و AL=30).
دستور IMUL – ضرب با علامت
این دستور برای اعدادی که منفی هم هستند استفاده میشود.
هم قواعد MUL را دارد؛ اما مقدار را signed در نظر میگیرد.
مثال:
mov eax, -3 mov ebx, 4 imul ebx
عمل: 4 × (−3) = −12
نتیجه در EAX قرار میگیرد.
دستور DIV – تقسیم بدون علامت
در تقسیم، مقدار مورد تقسیم همیشه داخل یک زوج رجیستر مخصوص است:
8 بیتی → AX / operand
16 بیتی → DX:AX / operand
32 بیتی → EDX:EAX / operand
نتیجه:
خارجقسمت: در AL/AX/EAX
باقیمانده: در AH/DX/EDX
مثال ۳۲ بیتی:
mov edx, 0 mov eax, 100 mov ebx, 7 div ebx
100 / 7 → خارجقسمت = 14 → داخل EAX
باقیمانده = 2 → داخل EDX
نکته مهم: قبل از تقسیم باید EDX را صفر کنیم، وگرنه مقدار قبلی محاسبه را خراب میکند.
دستور IDIV – تقسیم با علامت
مشابه DIV است، اما برای اعداد منفی استفاده میشود.
مثال:
mov eax, -20 cdq mov ebx, 3 idiv ebx
تابع cdq مقدار EDX را با علامت صحیح پر میکند.
−20 / 3 = −6
باقیمانده = −2
خارجقسمت → EAX
باقیمانده → EDX
دستور SHL – شیفت چپ (Shift Left)
این دستور بیتها را به سمت چپ میبرد.
هر شیفت چپ معادل ضرب در ۲ است.
مثال:
mov eax, 5 shl eax, 1
5 در دودویی = 00000101
بعد از یک شیفت چپ → 00001010
نتیجه = 10 (یعنی ×2)
دستور SHR – شیفت راست بدون علامت
برای اعداد unsigned استفاده میشود.
بیتهای سمت چپ با صفر پر میشود.
مثال:
mov eax, 16 shr eax, 1
16 / 2 = 8
(شیفت راست معادل تقسیم بر ۲)
دستور SAR – شیفت راست با علامت
برای اعداد signed است.
در این نوع شیفت، بیت علامت حفظ میشود.
مثال:
mov eax, -8 sar eax, 1
در دودویی دو مکمل، -8 با حفظ بیت علامت به سمت راست شیفت داده میشود.
نتیجه = -4
(معادل تقسیم صحیح بر ۲)
Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com