Mam taki krótki kod w C++:
#include <iostream>
using namespace std;
int triangle(int width, int height)
{
int array[5] = {0,1,2,3,4};
int area;
area = width * height / 2;
return area;
}
int main()
{
triangle(2, 2);
return 0;
}
Disassembler funkcję tłumaczy tak:
0x401350 push ebp
0x401351 mov ebp,esp
0x401353 sub esp,0x20
0x401356 mov DWORD PTR [ebp-0x18],0x0
0x40135d mov DWORD PTR [ebp-0x14],0x1
0x401364 mov DWORD PTR [ebp-0x10],0x2
0x40136b mov DWORD PTR [ebp-0xc],0x3
0x401372 mov DWORD PTR [ebp-0x8],0x4
0x401379 mov eax,DWORD PTR [ebp+0x8]
0x40137c imul eax,DWORD PTR [ebp+0xc]
0x401380 mov edx,eax
0x401382 shr edx,0x1f
0x401385 add eax,edx
0x401387 sar eax,1
0x401389 mov DWORD PTR [ebp-0x4],eax
0x40138c mov eax,DWORD PTR [ebp-0x4]
0x40138f leave
0x401390 ret
Z tego co rozpisuje sobie na kartce stos wygląda tak:
-32 -28 -24 -20 -16 -12 -8 -4 0 +4 +8 +12
[ ][local area][ 0 ][ 1 ][ 2 ][ 3 ][ 4 ][ ? ][OLD EBP][ RET ][HEIGHT][WIDTH]
^ ^
esp ebp
Te liczby na górze to pozycja od epb, któremu został przypisany adres poprzedniego esp instrukcją mov ebp, esp.
I jeśli dobrze to rozpisałem to zastanawia mnie co znajduje się na pozycji [epb-4] i dlaczego wskaźnik esp powędrował, aż na pozycję ebp-32, skoro jest tylko jedna zmienna lokalna area, która powinna być pod adresem ebp-28. I dlaczego ta zmienna lokalna nie jest wykorzystywana w dalszych instrukcjach tylko zamiast tego inne rejestry?