堆栈:函数嵌套调用

实现的功能:两层函数调用,外层函数的传入的两个参数再传到子函数中相加,实现四个数相加返回

004010E8  |.  6A 03         PUSH 3                                   ;  压入3
004010EA  |.  6A 02         PUSH 2                                   ;  压入2
004010EC  |.  6A 01         PUSH 1                                   ;  压入1
004010EE  |.  E8 12FFFFFF   CALL StackDem.00401005                   ;  压入CALL地址+指令长度,再调用CALL
004010F3  |.  83C4 0C       ADD ESP,0C                               ;  外平栈
004010F6  |.  33C0          XOR EAX,EAX                              ;  清空eax

堆栈:函数嵌套调用

进入00401005 CALL

00401070  /> \55            PUSH EBP                                 ;  保存ebp
00401071  |.  8BEC          MOV EBP,ESP                              ;  提升栈底
00401073  |.  83EC 48       SUB ESP,48                               ;  提升栈顶
00401076  |.  53            PUSH EBX                                 ;  压入ebx
00401077  |.  56            PUSH ESI                                 ;  压入esi
00401078  |.  57            PUSH EDI                                 ;  压入edi
00401079  |.  8D7D B8       LEA EDI,DWORD PTR SS:[EBP-48]            ;  提升栈顶的低地址赋值给edi
0040107C  |.  B9 12000000   MOV ECX,12                               ;  ecx 为 0x12
00401081  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC                         ;  eax 为 0xCCCCCCCC
00401086  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]              ;  将eax的值赋值给 之前提升的栈顶和栈底之间的值
00401088  |.  C745 FC 02000>MOV DWORD PTR SS:[EBP-4],2               ;  给初始化中的第一个地址赋值为2
0040108F  |.  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+C]             ;  将压入的第一个参数的值 赋值 给eax
00401092  |.  50            PUSH EAX                                 ;  压入 第一个参数的值
00401093  |.  8B4D 08       MOV ECX,DWORD PTR SS:[EBP+8]             ;  将压入的第二个参数的值 赋值 给eax
00401096  |.  51            PUSH ECX                                 ;  压入 第二个参数的值
00401097  |.  E8 6EFFFFFF   CALL StackDem.0040100A
0040109C  |.  83C4 08       ADD ESP,8                                ;  恢复入CALL之前的栈顶
0040109F  |.  8945 F8       MOV DWORD PTR SS:[EBP-8],EAX             ;  把上面的CALL返回值 赋值给这个CALL中处理的第二个参数
004010A2  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ;  把子CALL中的参数赋值给当前eax
004010A5  |.  0345 F8       ADD EAX,DWORD PTR SS:[EBP-8]             ;  上面两个值相加
004010A8  |.  0345 10       ADD EAX,DWORD PTR SS:[EBP+10]            ;  上面两个值相加完之后再加上这个CALL中压入的第一个参数
004010AB  |.  5F            POP EDI
004010AC  |.  5E            POP ESI
004010AD  |.  5B            POP EBX
004010AE  |.  83C4 48       ADD ESP,48                               ;  恢复刚入CALL之前的栈顶
004010B1  |.  3BEC          CMP EBP,ESP                              ;  比较栈顶和栈底是否相等
004010B3  |.  E8 68000000   CALL StackDem.00401120                   ;  检查堆栈平衡
004010B8  |.  8BE5          MOV ESP,EBP                              ;  把刚入CALL的时候堆栈中的栈底赋值给栈顶
004010BA  |.  5D            POP EBP                                  ;  恢复入CALL之前的栈底
004010BB  \.  C3            RETN

堆栈:函数嵌套调用

进入0040100A

00401030  /> \55            PUSH EBP                                 ;  压入ebp
00401031  |.  8BEC          MOV EBP,ESP
00401033  |.  83EC 44       SUB ESP,44
00401036  |.  53            PUSH EBX
00401037  |.  56            PUSH ESI
00401038  |.  57            PUSH EDI
00401039  |.  8D7D BC       LEA EDI,DWORD PTR SS:[EBP-44]
0040103C  |.  B9 11000000   MOV ECX,11
00401041  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
00401046  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]              ;  初始化垃圾数据
00401048  |.  C745 FC 0A000>MOV DWORD PTR SS:[EBP-4],0A              ;  初始化的第一个数据 赋值为0x0A
0040104F  |.  8B45 08       MOV EAX,DWORD PTR SS:[EBP+8]             ;  把压入的第二个参数的值 赋值给eax
00401052  |.  0345 0C       ADD EAX,DWORD PTR SS:[EBP+C]             ;  把压入的第一个参数的值 添加给eax
00401055  |.  0345 FC       ADD EAX,DWORD PTR SS:[EBP-4]             ;  把初始化的第一个数据 加给 eax
00401058  |.  5F            POP EDI
00401059  |.  5E            POP ESI
0040105A  |.  5B            POP EBX
0040105B  |.  8BE5          MOV ESP,EBP
0040105D  |.  5D            POP EBP
0040105E  \.  C3            RETN

堆栈:函数嵌套调用

上一篇:C语言中的数组、字符串、指针反汇编学习笔记


下一篇:硬核知识大全 作为程序员不得不了解