有时候为了代码的高效性,需要在stack上分配内存。一般而言如果不通过额外的寄存器,只通过esp指针是没法实现在stack的上的内存的动态分配的,因为compile没法通过单纯一个esp指针来实现变量的相对地址的管理。
例如要实现如下类似函数:
int foo(int n)
{
int x=100; // assume it's not put in a register.
char* p=(char*)dynamically_allocate_on_the_stack(n);
return x;
}
默认情况下compiler生成的stack操作代码是没法完成这个任务的!
sub esp,8
mov dword ptr [esp+4], 100 ; assigns a value to x
sub esp, [esp+12] ; dynamically allocates the stuff
mov [esp+???], esp ; assign that to p
mov eax,[esp+???] ; loads x
add esp, ??? ; where could we store the amount of stack used?
ret
这样一搞,compiler就疯了,它根本不知道变量x相对于栈顶指针esp的偏移量了,也就没法访问变量x了。
为此我们需要引入别的寄存器来解决该问题,一般而言ebp在此就派上用场了
解决方法也是很简单,就是多用一个ebp寄存器来额外保存刚进来时的esp,这样就可以确定变量x的相对地址了。
push ebp ; needs to save this register
mov ebp, esp ; this register is now reserved for this usage
sub esp,8 ; stack space for x and p
mov [ebp-4], 100 ; assigns 100 to x
sub esp, [ebp+8] ; allocates space on stack
mov [ebp-8], esp ; assigns it to p
mov eax, [ebp-4] ; loads x
mov esp, ebp
pop ebp ; clean up stack frame
ret