为什么我有PUSH ecx?

use*_*112 5 x86 assembly

有人可以告诉我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)

Igo*_*sky 9

push ecx分配的4个字节在堆栈上的本地变量(mh).实际内容ecx无关紧要 - 分配的插槽会立即被覆盖0CCCCCCCCh(Visual C++在调试版本中使用此神奇值来标记未初始化的变量).

VISUAL C++经常使用push ecxpop ecx作为替代品sub esp, 4add esp, 4.为什么?有几个原因:

push ecx并且pop ecx是单字节指令,而addsub是每次三个字节.差异可能不是很大,但所有功能中所有保存的字节可能会增加很多东西.

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.