有人可以告诉我push ecx
下面两条说明的目的是什么?我无法理解他们应该做什么?
我意识到push epb
正在保存堆栈基指针,然后mov epb, esp
将堆栈指针分配给前一个堆栈基指针.
int main(){
01301190 push ebp
01301191 mov ebp,esp
01301193 push ecx ;here??
01301194 mov dword ptr [h],0CCCCCCCCh
int h = my_func(1,3);
int my_func(int a, int b){
01301160 push ebp
01301161 mov ebp,esp
01301163 push ecx ;here??
01301164 mov dword ptr [m],0CCCCCCCCh
int m = 0;
0130116B mov dword ptr [m],0
m = a*b;
01301172 mov eax,dword ptr [a]
01301175 imul eax,dword ptr [b]
01301179 mov dword ptr [m],eax
return m;
0130117C mov eax,dword ptr [m]
}
0130117F mov esp,ebp
}
01301181 pop ebp
01301182 ret
Run Code Online (Sandbox Code Playgroud)
在push ecx
分配的4个字节在堆栈上的本地变量(m
和h
).实际内容ecx
无关紧要 - 分配的插槽会立即被覆盖0CCCCCCCCh
(Visual C++在调试版本中使用此神奇值来标记未初始化的变量).
VISUAL C++经常使用push ecx
并pop ecx
作为替代品sub esp, 4
和add esp, 4
.为什么?有几个原因:
push ecx
并且pop ecx
是单字节指令,而add
并sub
是每次三个字节.差异可能不是很大,但所有功能中所有保存的字节可能会增加很多东西.
ecx
被认为是被函数调用破坏了,因此pop ecx
在函数调用之后将其删除是安全的.所以你经常会看到如下代码:
push arg1 ; push an argument
call __func1 ; call the function
pop ecx ; restore the stack
Run Code Online (Sandbox Code Playgroud)
因为push
,没有特别的理由可以使用ecx
- 任何基本寄存器都可以.我猜它只是选择了对称性,或者不与像esi
或的非易失性寄存器的实际保存相混淆edi
.