将位置4的地址值赋给EDI寄存器;
将位置4到位置3之间的内存全部赋值为0CCCCCCCCh(由低到高)
此时ESP指向位置5
7
foo
函数
mov dword ptr [a],1
mov dword ptr [b],2
通过指针访问,将局部变量区域中的a和b赋值;
注意:a和b并不是连续存放在栈中的,也没有将局部变量的空间占满。
ESP位置不变
8
foo
函数
mov eax,dword ptr [a]
mov dword ptr [b],eax
通过EAX寄存器来完成局部变量的赋值操作;依然是指针访问。
ESP位置不变
9
foo
函数
mov eax,dword ptr [i]
8,9,10三步实现foo函数返回;
通过EAX寄存器来传递返回值
ESP依然指向位置5,即最后一个被压栈的寄存器
10
foo
函数
pop edi
pop esi
pop ebx
将此前压栈的寄存器出栈
ESP指针指向位置4
11
foo
函数
mov esp,ebp
pop ebp
将EBP值赋给ESP指针,意味着释放掉了局部变量的内存空间
ESP指向位置3
将此前压栈的旧EBP值出栈,赋给EBP
ESP指向位置2
12
foo
函数
ret
函数返回,会根据此前压栈的返回地址跳转到下一条指令的位置
ESP指向位置1
13
main
函数
add esp,4
释放此前压栈的foo函数参数,至此,foo函数彻底结束了它的生命
ESP指向位置0
14
main
函数
mov dword ptr [a],eax
通过EAX传递返回值,将返回值赋给变量a;
main函数中有关调用foo函数的内容至此结束。
需要说明的是,在函数完成了现场保护之类的初始化工作之后,ESP会始终指向当前函数的栈空间顶,此时,若当前函数又调用了另一个函数,则会将此时的EBP视为旧EBP压栈,而与新调用的函数有关的内容则会从当前ESP所指向位置开始压栈。