函数堆栈110(110)

http://www.cnblogs.com/Binhua-Liu/archive/2010/08/24/1803095.html

---------------------
二进制 局部 - return -  参数 -//我去对不齐。。。
           -    -   -
           -    -   -
---------------------

堆栈由处理器支持
高地址向地地址扩展,栈顶地址不断减小,越后入,地址越低。

---------------------
-   -高
-   -
-   -
- - -低

32位堆栈每个数据单元大小4字节,这便和数据对齐相关了。

普及下寄存器EBP(extended base pointer) ESP(extended stack pointer)

指令,push 寄存器指针减4,拷贝数据到ESP指向地址

pop 寄存器拷贝出数据,加4.

上主菜

先对参数的压入栈。我觉得这个过程完成形参对实参的赋值,所以压入的是实参。

然后是返回的压入,压入返回指令。

我认为以上的压入在32为下4字节内压入类型,8字节压入俩寄存器表示的类型,上压入指针

压入EBP寄存指针。访问参数和局部变量使用。调用函数形成链表。

ESP赋值EBP,EBP指向中间。

局部变量的压栈

通用寄存器压栈

开始执行二进制代码.

假设执行函数前堆栈指针ESP为NN
push   p2    ;参数2入栈, ESP -= 4h , ESP = NN - 4h
push   p1    ;参数1入栈, ESP -= 4h , ESP = NN - 8h
call test    ;压入返回地址 ESP -= 4h, ESP = NN - 0Ch  
;//进入函数内
{
push   ebp                        ;保护先前EBP指针, EBP入栈, ESP-=4h, ESP = NN - 10h
mov    ebp, esp                   ;设置EBP指针指向栈顶 NN-10h
mov    eax, dword ptr  [ebp+0ch]  ;ebp+0ch为NN-4h,即参数2的位置
mov    ebx, dword ptr  [ebp+08h]  ;ebp+08h为NN-8h,即参数1的位置
sub    esp, 8                     ;局部变量所占空间ESP-=8, ESP = NN-18h
...
add    esp, 8                     ;释放局部变量, ESP+=8, ESP = NN-10h
pop    ebp                        ;出栈,恢复EBP, ESP+=4, ESP = NN-0Ch
ret    8                          ;ret返回,弹出返回地址,ESP+=4, ESP=NN-08h, 后面加操作数8为平衡堆栈,ESP+=8,ESP=NN, 恢复进入函数前的堆栈.
}
//看完汇编后,再看EBP和ESP的定义,哦,豁然开朗,
原来ESP就是一直指向栈顶的指针,而EBP只是存取某时刻的栈顶指针,以方便对栈的操作,如获取函数参数、局部变量等。
// //