سلام! قراره با همدیگه یه پروژه خیلی ساده با اسمبلی بسازیم که یه ماشینحساب کوچولو باشه.
این برنامه، دو تا عدد از کاربر میگیره و جمعشون رو نمایش میده.
همراه من باشید… ✨
پیشنیازها
• یه ویرایشگر متن ساده: nano یا vim و…
• اسمبلر: مثل NASM
آمادهسازی محیط
اگه NASM رو نداری، از اینجا دانلود و نصبش کن. (میتونی از سایت رسمی خودش یا مخازن لینوکسی به وسیله پکیجمنیجرهایی مثل APT
یا PACMAN
و… دریافتش کنی(متناسب با توزیع OS))
میتونید با nasm -v
چک کنید که نصب شده یا نه.
یه پوشه بساز برای فایلهای پروژهمون.
نوشتن برنامه
یه فایل جدید باز کنید و اسمش رو بذارید مثلا calc.asm
(calc مخفف calculator)
تو این فایل، کد زیر رو بنویسید:
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 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
section .data msg1 db "Enter 1st num: ", 0 len_msg1 equ $ - msg1 msg2 db "Enter 2nd num: ", 0 len_msg2 equ $ - msg2 resultMsg db "Result: ", 0 len_resultMsg equ $ - resultMsg section .bss num1 resb 2 num2 resb 2 buffer resb 2 section .text global _start _start: ; Print first message mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, len_msg1 int 0x80 ; Read first number mov eax, 3 mov ebx, 0 mov ecx, num1 mov edx, 2 ; read 1 digit + newline int 0x80 ; Print second message mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, len_msg2 int 0x80 ; Read second number mov eax, 3 mov ebx, 0 mov ecx, num2 mov edx, 2 int 0x80 ; Convert ASCII to integer movzx eax, byte [num1] sub eax, '0' movzx ebx, byte [num2] sub ebx, '0' ; Add numbers add eax, ebx ; Convert result to ASCII add eax, '0' mov [buffer], al ; Print result message mov eax, 4 mov ebx, 1 mov ecx, resultMsg mov edx, len_resultMsg int 0x80 ; Print result number mov eax, 4 mov ebx, 1 mov ecx, buffer mov edx, 1 int 0x80 ; Exit mov eax, 1 xor ebx, ebx int 0x80 |
توضیح کد
بخش داده: متن پیامها و یه بافر کوچیک برای نمایش نتیجه رو توی data section تعریف کردیم.
بخش bss: اینجا حافظه لازم برای ذخیره اعداد رو رزرو کردیم.
بخش متنی (text): دستوراتمون رو اینجا مینویسیم.
پیامها رو با ست کردن 4 توی eax به عنوان دستور sys_write
چاپ میکنیم و ورودیها رو هم با 3 توی eax تحت sys_read
میگیریم.
هر بار برای اجرا کردن syscall از وقفه (interupt) 0x80 استفاده میکنیم.
اعداد رو از کاراکتر به عدد تبدیل میکنیم و با هم جمع میکنیم و نتیجه رو نمایش میدیم.
تامام… 😁
اگه هر سوالی داشتید یا ابهامی توی کد بود، کامنت بگذارید، پاسخ میدم…
اجرا و بررسی نتایج پخت و پزمون
دست به دامن ترمینال شو و با nasm خروجی بگیر:
1 2 3 |
nasm -f elf32 calc.asm -o calc.o ld -m elf_i386 calc.o -o calc |
حالا برنامت رو اجرا کن!
1 2 |
./calc |
توجه داشته باشید که این مطلب و بعضا مطالب دیگهای از وبلاگ، جنبه آموزشی داره؛ لذا گاهی لازمه مسائل اولیه و معمول رو هم توضیحات داد یا بهشون اشاره کرد. پس اگه به عنوان یه حرفهای مطالب رو مرور میکنید، شکیبا باشید. 😶
خب حالا شما توی کامنتا بگید چطور باید کاری کرد که بعد از دادن Result، لاین جدید باز کنه و مشکلی که توی ترمینال میبینیم، پیش نیاد. 😉