تشخیص ساختارهای برنامه نویسی در اسمبلی - قسمت چهارم
حلقه ها خیلی زیاد توی برنامه نویسی بکار میرن و یادگیری شناسایی اونها یکی از کارهای مهم میتونه باشه.
یکی ازین حلقه ها FOR هستش که خیلی زیاد استفاده میشه و 4تا قسمت داره:
مقداردهی اولیه
مقایسه
دستورات اجرایی
افزایش یا کاهش
یه نمونه از دستور for
int i;
for(i=0; i<100; i++)
{
printf("i equals %d\n", i);
}
توی این مثال, اول مقدار صفر به i داده میشه, سپس مقدار i با عدد 100 مقایسه میشه که اگه کوچکتر از 100 باشه دستور داخل بدنه (printf) اجرا میشه بعد از اون هم یک واحد به i اضافه میشه.این فرآیند تا زمانی که i بزرگتر یا مساوی با 100 بشه ادامه پیدا میکنه
حالا کد دیس اسمبل شده :
00401004 mov [ebp+var_4], 0 (1)
0040100B jmp short loc_401016 (2)
0040100D loc_40100D:
0040100D mov eax, [ebp+var_4] (3)
00401010 add eax, 1
00401013 mov [ebp+var_4], eax (4)
00401016 loc_401016:
00401016 cmp [ebp+var_4], 64h (5)
0040101A jge short loc_40102F (6)
0040101C mov ecx, [ebp+var_4]
0040101F push ecx
00401020 push offset aID ; "i equals %d\n"
00401025 call printf
0040102A add esp, 8
0040102D jmp short loc_40100D (7)
ما عملیاتی که توی کد بالا اتفاق میافته رو به 7 قسمت تقسیم کردیم:
1- مرحله ارزش دهی اولیه انجام میشه
2- ما با دستور jmp از ++i میپریم تا اول شرط رو چک کنیم
3- 4- اینا عملیات افزایش یک واحدی i رو انجام میدن
5- اینجا شرط با دستور cmp بررسی میشه
6- دستور jge اگه توی مقایسه بالا متغیر اول بزرگتر یا مساوی دومی باشه پرش رو انجام میده یعنی (i=>100) .این پرش به خارج از دستور for هستش.
اما اگه i<100 باشه دستوراتی که در ادامه jge هستند اجرا میشه (printf)
7- اینجا درست پس از اجرای printf ما یک پرش به i++ انجام میدیم وقتی i یک واحد افزایش پیدا کردش دوباره شرط برررسی میشه و همین طور الا آخر..
حلقه while هم یکی از حلقه های پرکاربرد هستش که در ادامه بررسیش میکنیم:
int status=0;
int result = 0;
while(status == 0){
result = performAction();
status = checkResult(result);
}
کد بالا تا زمانی که checkResult صفر رو برگردونه اجرا میشه
00401036 mov [ebp+var_4], 0
0040103D mov [ebp+var_8], 0
00401044 loc_401044:
00401044 cmp [ebp+var_4], 0
00401048 jnz short loc_401063 (1)
0040104A call performAction
0040104F mov [ebp+var_8], eax
00401052 mov eax, [ebp+var_8]
00401055 push eax
00401056 call checkResult
0040105B add esp, 4
0040105E mov [ebp+var_4], eax
00401061 jmp short loc_401044 (2)
کد اسمبلی بالا مشابه حلقه for هستش با این تفاوت که دیگه قسمت افزایشی نداره.توی مرحله اول یه پرش شرطی و توی مرحله دوم یه پرش غیرشرطی وجود داره.میبینید که تنها راه برای متوقف کردن این حلقه اینه که پرش شرطی مرحله اول انجام بشه.