
استک بخشی از حافظه است که برنامه برای ذخیره موقت دادههای مربوط به اجرای توابع از آن استفاده میکند.
هر بار که یک تابع اجرا میشود، یک بلوک حافظه به نام Stack Frame برای آن ساخته میشود.
در این Stack Frame دادههای زیر ذخیره میشود:
متغیرهای محلی (Local variables)
مثلاً:
int x = 5;
پارامترهای ورودی تابع (Function parameters)
مثلاً:
void add(int a, int b) { ... }
آدرس بازگشت (Return address)
برای اینکه برنامه بداند پس از اتمام تابع، به کجا باید برگردد.
چرا به آن STACK میگویند؟
چون دقیقاً مثل روی هم گذاشتن بشقابها کار میکند:
آخرین تابعی که صدا زده میشود اول خارج میشود.
➤ این ساختار را LIFO میگویند (Last In, First Out)
رفتار حافظه استک به صورت خلاصه:
.هنگام ورود به یک تابع:
یک Stack Frame جدید ایجاد میشود.
.هنگام خروج از تابع:
Stack Frame کامل پاک میشود → یعنی متغیرهای محلی نابود میشوند.
مزایای استک
.سرعت بسیار بالا
.مدیریت خودکار حافظه (نیازی به delete یا free نیست)
.امنیت بالاتر
محدودیتهای استک
. حجم کم (معمولاً چند مگابایت)
.مناسب ذخیرهسازی دادههای حجیم نیست
.در صورت استفاده زیاد → خطای Stack Overflow

توضیح اسمبلی تابع func(int a)
push ebp mov ebp,esp push ecx mov dword ptr ss:[ebp-4],3 mov esp,ebp pop ebp ret int3
مرحلهبهمرحله:
اول:
push ebp
مقدار قبلی ebp را روی استک میگذارد.
هدف: ساختن Stack Frame جدید.
دوم:
mov ebp, esp
مقدار ESP (بالای استک) را در EBP میریزد.
از این لحظه به بعد، ebp مرجع اصلی متغیرها و آرگومانها میشود.
سوم:
push ecx
کامپایلر یک فضای اضافه برای Local variables رزرو میکند.
این همان فضای لازم برای متغیر b است.
حالا استک این شکلی میشود:
[ebp+8] → آرگومان a [ebp] → ebp قبلی [ebp-4] → متغیر محلی b
چهارم:
mov dword ptr ss:[ebp-4],3
مقدار 3 را در آدرس [ebp-4] قرار میدهد.(در استک)
یعنی مقدار متغیر محلی b = 3
پنجم:
mov esp, ebp
استک را برمیگرداند به حالت قبل از تعریف متغیرها.
یعنی Local variable ها پاک میشوند.
ششم:
pop ebp
مقدار قبلی EBP را از استک برمیدارد و برمیگرداند.
Stack Frame تابع func تمام شد.
هفتم:
ret
به آدرس برگشت در تابع main میرود.
هشتم:
int3
این دستور برای دیباگر است و در اجرای عادی برنامه استفاده نمیشود.
توضیح اسمبلی تابع main()
...
اول:
mov dword ptr ss:[ebp-4],2
مقدار 2 را در [ebp-4] ذخیره میکند → یعنی: (در استک)
x = 2
دوم:
mov eax, dword ptr ss:[ebp-4]
مقدار متغیر x (که ۲ است) را در رجیستر eax میریزد.
قرار است این مقدار را به func پاس بدهد.
سوم:
push eax
مقدار آرگومان (۲) را میگذارد روی استک.
تابع func آرگومان خود را از [ebp+8] میگیرد.
چهارم:
call func
به تابع func میرود
آدرس برگشت را روی استک میگذارد.
پنجم:
add esp,4
بعد از برگشت از func، آرگومان را از استک پاک میکند:
ششم:
xor eax, eax
مقدار eax = 0
این مقدار return تابع main است.
هفتم:
mov esp, ebp pop ebp ret
پاک کردن stack frame
پایان تابع main
Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com