堆栈图(2)
相关概念
函数:
计算机中的函数是一个固定的一个程序段,或称其为一个子程序,它在可以实现固定运算功能的同时还带有一个入口和一个出口,所谓的入口,就是函数所带的各个参数,我们可以通过这个入口,把函数的参数值代入子程序,供计算机处理,所谓出口,就是指函数的计算结果,也称为返回值,在计算机求得之后,由此口带回给调用它的程序。
汇编中的函数:
函数有一些自己特有的特征(函数有一个入口和一个出口)。
函数的入口:
这里传进去的2和1是参数,也可以说是函数的入口。
无参:指函数,也可以说一段固定的程序,它有入口也有出口;入口就是允许你可以把参数传进去;出口就是这段函数需要有个办法把得出的结果返回,也可以不返回。
传参数不一定要通过堆栈传,也可以用那8个通用寄存器,可以把值放进寄存器。只要我们能把参数传进去,那它就是参数了,不要认为只有PUSH才是传参数。
函数的出口:
函数也可以看做一段固定的代码,这个代码执行了某些特定的功能:提供一个入口,允许我们把外来的值传进来,传进来的值称为参数,这个参数可以通过寄存器传进来也可以通过内存器传进来,没有固定的套路;当这段程序执行完,会得到一个结果,这时候函数会提供一个出口,这个出口允许我们把计算的结果传过去,上面可以看到我们把值传到通用寄存器中,这个值叫返回值,当然一个函数也可以没有参数和返回值。
Windows堆栈:
注意:函数调用前后的堆栈一定要保持平衡。
堆栈图
左边标红的就是此次堆栈图的起点。
开始画,先记录EBP栈底0012FF80,ESP栈顶0012FF34。
上面有三个参数,PUSH完之后,我们就将这三个值传入了函数,也就是说我们把值压入了堆栈:
发现ESP位发生了变化,变成了0012FF28,而且那三个值已经压进堆栈里了。
接着CALL指令的时候按F7(F7就是在这一行遇到函数它可以跳进函数里面,然后再进行单步的执行)。
补充下
看看执行结果
JMP指令不影响堆栈,直接F8
PUSH EBP
MOV EBP,ESP
SUB ESP,48
将EBP放入ESP-4,EBP=ESP,ESP-48
提升栈顶
PUSH EBX
PUSH ESI
PUSH EDI
把EBX放进ESP-4 ESI再放进ESP-4 EDI放进ESP-4
压栈 ESP-c
验证一下
LEA EDI,DWORD PTR SS:[EBP-48]
MOV ECX,12
MOV EAX,CCCCCCCC
REP STOS DWORD PTR ES:[EDI]
将EBP-48的地址放进EDI里面,给ECX赋值一个立即数12,给EAX赋值CCCCCCCC,执行12次,每执行一次,EDI的值+4,每执行一次就会覆盖4个字节。
MOV DWORD PTR SS:[EBP-4],2
MOV EAX,DWORD PTR SS:[EBP+C]
将2写入EBP-4中 将EBP+C内存编号中的值放进EAX中,此时EAX的值为2 。
PUSH EAX
MOV ECX,DWORD PTR SS:[EBP+8]
PUSH ECX
把EAX放入ESP-4中 将EBP+8的值放进ECX中 再把ECX放进ESP-4
这里又调用一个函数,在函数里面可以调用另一个函数,称为 嵌套。
调用的新的函数
PUSH EBP
MOV EBP,ESP
SUB ESP,44
压栈,ESP -4,EBP = ESP,ESP -44
运行一下,发现和 我们写的一样
PUSH EBP
PUSH ESI
PUSH EDI
LEA EDI, DWORD PTR SS:[EBI-44]
MOV ECX, 11
MOV EAX, CCCCCCC
REP STOS DWORD PTR ES:[EDI]
赋值 ECX=11,赋值 EAX=CCCCCCCC,将EAX重复写到以EDI为首地址的缓冲区中,重复次数为11,每执行依次,EDI+4,EDI增加44
MOV DWORD PTR SS:[EBP -4], OA
MOV EAX, DWORD PTR SS:[EBP +8]
ADD EAX, DWORD PTR SS:[EBP +C]
ADD EAX, DWORD PTR SS:[EBI -4]
MOV ESP, EBP
POP EBP
ESP=EBP,EBP出栈,ESP-4
RETN (相当于下面两行代码)
LEA ESP[ESP +4]
MOV EIP[ESP -4]
ADD ESP, 8
MOV DWORD PTR SS:[EBP -8], EAX
MOV EAX, DWORD PTR SS:[EBP -4]
ADD EAX, DWORD PTR SS:[EBP -8]
ADD EAX, DWORD PTR SS:[EBI +10]
将EAX里的值放到EDI -8里,EAX=2,D+2,再+10,EAX变成12,不改变堆栈
C语言
在VC6中,进入函数的反汇编窗口:F7,F5,右键
在VC6中进入一个函数用F11
堆栈图:
C函数以及反汇编分析: