为什么我有PUSH ecx? [英] Why do I have PUSH ecx?

查看:91
本文介绍了为什么我有PUSH ecx?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以告诉我下面两条push ecx指令的目的是什么?我不明白他们应该做什么?

Could somebody please tell me what is the purpose of the two push ecx instructions below? I can't understand what they are supposed to be doing?

我意识到push epb正在保存栈基指针,然后mov epb, esp将栈指针分配给先前的栈基指针.

I realise the push epb is saving the stack base pointer and then mov epb, esp is assigning the stack pointer to the previous stack base pointer.

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  

推荐答案

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

The push ecx allocates 4 bytes on the stack for the local variable (m and h). The actual content of ecx does not matter - the allocated slot is immediately overwritten by 0CCCCCCCCh (this magic value is used by Visual C++ in debug builds to mark uninitialized variables).

Visual C ++通常使用push ecxpop ecx作为sub esp, 4add esp, 4的替代项.为什么?有几个原因:

Visual C++ often uses push ecx and pop ecx as alternatives to sub esp, 4 and add esp, 4. Why? There are several reasons:

push ecxpop ecx是单字节指令,而addsub分别是三个字节.差异可能不会很大,但是所有函数中所有保存的字节都可能累加起来.

push ecx and pop ecx are single-byte instructions, while add and sub are three byte each. The difference may not be huge, but all the saved bytes in all functions may add up to something substantial.

ecx被认为是由于函数调用而损坏的,因此在函数调用之后将其与pop ecx一起使用是很安全的.因此,您经常会看到类似以下的代码:

ecx is considered to be spoiled by a function call, so it's safe to trash it with pop ecx after function calls. So you often see code like:

  push arg1    ; push an argument
  call __func1 ; call the function
  pop ecx      ; restore the stack

对于push,没有真正的理由专门使用ecx-任何基本寄存器都可以.我想它只是出于对称性而选择的,或者不要与真正保存诸如esiedi的非易失性寄存器相混淆.

For push, there's no real reason to use ecx specifically - any of the basic registers would do. I guess it was just picked for symmetry, or to not be confused with real saving of a non-volatile register like esi or edi.

这篇关于为什么我有PUSH ecx?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆