堆栈是同一段进行插入删除的线性表 (先入后出)
栈式最基础的常见的数据结构之一
进入一个新的函数的时候 会开辟一个空间,存放需要的数据
int add(int a,int b,int c)
{
return a+b+c
}
int main()
{
add(1,2,3)
}
//add(1,2,3)反汇编中的代码
push 3 //将3压栈 ESP栈顶减少4个字节 相当于将3压入栈后 栈顶向上提升
push 2 //将2压栈 ESP栈顶减少4个字节 相当于将2压入栈后 栈顶向上提升
push 1 //将1压栈 ESP栈顶减少4个字节 相当于将1压入栈后 栈顶向上提升
call 00E0142E //将下一行地址压栈,并且跳转 简单理解保存函数的内存地址方便跳回,看到这个代码就是执行函数
//F11跳转进函数 jmp 00S002 //跳转到函数中
add esp,0Ch // 还原数据走这一句 将栈顶跳转到 push之后 增加 12 个字节 3 2 1 每一个整形是4字节加起来是12
//跳到这里
//ESP EBP 栈的寄存器 S栈顶 B栈底
//EAX EBX ECX EDX 是存基础变量的一些数据
//EIP 是存放即将运行下一行代码的地址
push ebp //将栈底的地址放入栈中,栈底的地址是上一个方法的底部,在压入栈底的同时,栈顶也向上提升
mov ebp,esp //将esp赋值给ebp 将栈顶的值赋值给栈底 把栈底拉上来,方便开辟新空间
sub esp,0C0H //在将栈顶的值拉高
push ebx //备份寄存器 保存多少看编译器 栈顶提升
push esi //备份寄存器 保存多少看编译器 栈顶提升
push edi //备份寄存器 保存多少看编译器 栈顶提升
//下面的语句是运算过程
lea edi,[ebp+FFFFF4 0h]
nov ecx,30h
nov eax,0CCCCCCCCh
rep stos dvord ptr es:[edi]
mov ecx,0E0F027h
call 00E01280
//下面是运算的代码
mov eax,dword ptr [ebp+8] //dword ptr 相当于4字节 可以不写,ebp+8是参数1
add eax,dword ptr [ebp+0Ch] //ebp+8是参数2 第一个参数加第二个参数
add eax,dword ptr [ebp+10h] //ebp+8是参数3 第一个参数和第二个参数的和在加第三个参数
mov dword ptr [ebp-8],eax //将和复制给局部变量
mov eax,dword ptr [ebp-8] //再将值赋值给eax 当作返回值,eax经常会被用当返回值
//执行完后还原的操作
pop edi //将备份的寄存器 弹出 并且栈顶下降
pop esi //将备份的寄存器 弹出 并且栈顶下降
pop ebx //将备份的寄存器 弹出 并且栈顶下降
add esp,0C0H //将栈顶还原位置 这个时候 栈顶与栈底相同
pop ebp //弹出栈底 ebp变回上一次方法的栈底地址,栈底下降一级
ret //返回call保存的地址 并且栈顶下降一级,跳转到刚进入的add esp,0Ch 语句