▶ 测试在屏幕上显示堆栈帧的库函数 WriteStackFrame 和 WriteStackFrameName,代码和输出放在一起
1 INCLUDE Irvine32.inc 2 INCLUDE macros.inc 3 4 aProc PROTO, x: DWORD, y: DWORD 5 dProc PROTO, x: DWORD 6 7 .code 8 main PROC 9 mov eax, 0EAEAEAEAh 10 mov ebx, 0EBEBEBEBh 11 mov ecx, 0ECECECECh 12 mov edx, 0EDEDEDEDh 13 INVOKE aProc, 1111h, 2222h ; 有参数,有局部变量,有保存寄存器 14 15 call bProc ; 无参数,无局部变量,无保存寄存器 16 17 call cProc ; 无参数,无局部变量,有保存寄存器 18 19 INVOKE dProc, 1111h ; 有参数,无局部变量,无保存寄存器 20 21 call eProc ; 无参数,有局部变量,无保存寄存器 22 23 push 4444h 24 push 3333h 25 call fProc ; 手写调用子过程,有参数,有局部变量,有保存寄存器 26 27 call gProc ; 五参数,无局部变量,有保存寄存器,没有将 ebp 正确压栈 28 29 call WaitMsg 30 exit 31 main ENDP 32 33 aProc PROC USES eax ebx, x: DWORD, y: DWORD 34 LOCAL a:DWORD, b:DWORD 35 .data 36 PARAMS = 2 37 LOCALS = 2 38 SAVED_REGS = 2 39 40 .code 41 mov a, 0AAAAh 42 mov b, 0BBBBh 43 44 INVOKE WriteStackFrame, PARAMS, LOCALS, SAVED_REGS ; 输出参数,返回地址,ebp,局部变量,USES 的寄存器 45 mWriteLn "aProc, 2 parameters, 2 local variables, 2 saved registers" 46 call CrLf 47 ret 48 aProc ENDP 49 50 COMMENT ! aProc 输出结果 51 Stack Frame 52 53 00002222 ebp+12 (parameter) 54 00001111 ebp+8 (parameter) 55 001F36E3 ebp+4 (return address) 56 00EFFC88 ebp+0 (saved ebp) <--- ebp 57 0000AAAA ebp-4 (local variable) 58 0000BBBB ebp-8 (local variable) 59 EAEAEAEA ebp-12 (saved register) 60 EBEBEBEB ebp-16 (saved register) <--- esp 61 62 aProc, 2 parameters, 2 local variables, 2 saved registers 63 ! 64 65 bProc PROC 66 .data 67 bProcName BYTE "bProc", 0 68 69 .code 70 push ebp 71 mov ebp, esp 72 73 INVOKE WriteStackFrameName, 0, 0, 0, ADDR bProcName ; 比 WriteStackFrame 多了名字,bProcName 不算栈中的局部变量 74 mWriteLn "bProc, 0 parameters, 0 local variables, 0 saved registers" 75 call CrLf 76 mov esp, ebp 77 pop ebp 78 ret 79 bProc ENDP 80 81 COMMENT ! bProc 输出结果 82 Stack Frame for bProc 83 84 001F36E8 ebp+4 (return address) 85 00EFFC88 ebp+0 (saved ebp) <--- ebp <--- esp 86 87 bProc, 0 parameters, 0 local variables and 0 saved registers 88 ! 89 90 cProc PROC USES eax edx 91 .data 92 cProcName BYTE "cProc", 0 93 94 .code 95 push ebp 96 mov ebp, esp 97 98 INVOKE WriteStackFrameName, 0, 0, 2, ADDR cProcName 99 mWriteLn "cProc, 0 parameters, 0 local variables, 2 saved registers" 100 call CrLf 101 mov esp, ebp 102 pop ebp 103 ret 104 cProc ENDP 105 106 COMMENT ! 107 Stack Frame for cProc 108 109 00DE36ED ebp+12 (return address) 110 EAEAEAEA ebp+8 (saved register) ; 保存寄存器放到了返回地址和 ebp 之间,但 ebp 正确,扔能正常返回 111 EDEDEDED ebp+4 (saved register) 112 010FFA48 ebp+0 (saved ebp) <--- ebp <--- esp 113 114 cProc, 0 parameters, 0 local variables, 2 saved registers 115 ! 116 117 dProc PROC, x: DWORD 118 .data 119 dProcName BYTE "dProc", 0 120 121 .code 122 INVOKE WriteStackFrameName, 1, 0, 0, ADDR dProcName 123 mWriteLn "dProc, 1 parameter, 0 local variables, 0 saved registers" 124 call CrLf 125 ret 126 dProc ENDP 127 128 COMMENT ! 129 Stack Frame for dProc 130 131 00001111 ebp+8 (parameter) 132 009B36F7 ebp+4 (return address) 133 00CFFA50 ebp+0 (saved ebp) <--- ebp <--- esp 134 135 dProc, 1 parameter, 0 local variables, 0 saved registers 136 ! 137 138 eProc PROC 139 LOCAL a: DWORD 140 .data 141 eProcName BYTE "eProc", 0 142 143 .code 144 mov a, 0AAAAh 145 INVOKE WriteStackFrameName, 0, 1, 0, ADDR eProcName 146 mWriteLn "eProc, 0 parameters, 1 local variable, 0 saved registers" 147 call CrLf 148 ret 149 eProc ENDP 150 151 COMMENT ! 152 Stack Frame for eProc 153 154 009B36FC ebp+4 (return address) 155 00CFFA50 ebp+0 (saved ebp) <--- ebp 156 0000AAAA ebp-4 (local variable) <--- esp 157 158 eProc has 0 parameters, 1 local variable, 0 saved registers 159 ! 160 161 fProc PROC 162 .data 163 fProcName BYTE "fProc", 0 164 165 .code 166 push ebp ; 栈基指针 167 mov ebp, esp 168 sub esp, 12 169 push eax ; 保存寄存器 170 push ebx 171 push ecx 172 push edx 173 mov DWORD PTR [ebp-4], 0AAAAh ; 局部变量 174 mov DWORD PTR [ebp-8], 0BBBBh 175 mov DWORD PTR [ebp-12], 0CCCCh 176 INVOKE WriteStackFrameName, 2, 3, 4, ADDR fProcName 177 mWriteLn "fProc, 2 parameters, 3 local variables, 4 saved registers" 178 call CrLf 179 pop edx ; 恢复保存寄存器 180 pop ecx 181 pop ebx 182 pop eax 183 mov esp, ebp ; 恢复栈基指针 184 pop ebp 185 ret 8 ; 清楚局部变量 186 fProc ENDP 187 188 COMMENT ! 189 Stack Frame for fProc 190 191 00004444 ebp+12 (parameter) 192 00003333 ebp+8 (parameter) 193 001F370B ebp+4 (return address) 194 00D7FF18 ebp+0 (saved ebp) <--- ebp 195 0000AAAA ebp-4 (local variable) 196 0000BBBB ebp-8 (local variable) 197 0000CCCC ebp-12 (local variable) 198 EAEAEAEA ebp-16 (saved register) 199 EBEBEBEB ebp-20 (saved register) 200 ECECECEC ebp-24 (saved register) 201 EDEDEDED ebp-28 (saved register) <--- esp 202 203 fProc, 2 parameters, 3 local variables, 4 saved registers 204 ! 205 206 gProc PROC 207 .data 208 gProcName BYTE "gProc", 0 209 210 .code 211 INVOKE WriteStackFrame, 0, 0, 2 212 INVOKE WriteStackFrameName, 0, 0, 2, ADDR gProcName 213 mWriteLn "gProc, 0 parameters, 0 local variables, 2 saved registers" 214 call CrLf 215 ret 216 gProc ENDP 217 END main 218 219 COMMENT ! 220 Stack Frame ; WriteStackFrame 不能正常工作 221 222 The stack frame is invalid 223 Stack Frame for gProc ; WriteStackFrameName 还行 224 225 1CEA31B6 ebp+12 (return address) 226 00E77000 ebp+8 (saved register) 227 77CE305A ebp+4 (saved register) 228 00DFF904 ebp+0 (saved ebp) <--- ebp <--- esp 229 230 gProc, 0 parameters, 0 local variables, 2 saved registers 231 !