我采用了对照的方法来学习汇编,也就是通过查看VC中的代码对应的汇编程序的执行来分析。
如下是一段简单的VC中的C语言:
#include"stdio.h" int gt(int a,int b) { return a+b; } int main() { int x=12; int y=1; int c=gt(x,y); int z=0; return 0; }
那么我们一步步分析这段函数对应的汇编代码。
0040D4A1 mov eax,0CCCCCCCCh 0040D4A6 rep stos dword ptr [edi]
//从这里开始程序代码
8: int x=12;
0040D4A8 mov dword ptr [ebp-4],0Ch //int x=12的汇编 其中ebp是帧指针,指向栈活动空间的底部,表示该活动空间从这里开始
//其中ebp-4就是变量x。在这里我们可以看到局部变量是放在栈上的,因此可以用
//ebp直接访问到 9: int y=1; 0040D4AF mov dword ptr [ebp-8],1 //同上分析 10: int c=gt(x,y); 0040D4B6 mov eax,dword ptr [ebp-8] //把y的值先付给通用寄存器eax 0040D4B9 push eax //eax的值入栈 这里为什么不直接把变量y入栈?因为push操作数只支持寄存器
//注意,这里先入栈的是变量y的值 0040D4BA mov ecx,dword ptr [ebp-4] //同上,将x的值压入栈。这里可以说明,参数入栈是从右往左 0040D4BD push ecx 0040D4BE call @ILT+5(gt) (0040100a) //调用函数 0040D4C3 add esp,8 //esp是栈指针,子函数在这里返回 0040D4C6 mov dword ptr [ebp-0Ch],eax //eax存放了函数的返回值,将返回值赋给变量c 11: int z=0; 0040D4C9 mov dword ptr [ebp-10h],0 12: return 0; 0040D4D0 xor eax,eax 13: }
//程序代码结束处 0040D4D2 pop edi
我们继续分析调用的子函数部分
1: #include"stdio.h" 2: int gt(int a,int b) 3: { 00401010 push ebp //首先把旧的ebp入栈 00401011 mov ebp,esp //然后把栈指针的值赋给ebp,ebp表示指向了新的栈活动空间 00401013 sub esp,40h //esp的值减去40h,表示栈指针往下移动40h字节 00401016 push ebx ebx的值入栈 00401017 push esi esi的值入栈 00401018 push edi edi的值入栈 00401019 lea edi,[ebp-40h] 0040101C mov ecx,10h 00401021 mov eax,0CCCCCCCCh 00401026 rep stos dword ptr [edi] 4: return a+b; 00401028 mov eax,dword ptr [ebp+8] //参数a的值赋给eax寄存器 0040102B add eax,dword ptr [ebp+0Ch]//将eax的寄存器的值和参数b的值相加,并且放到eax 注意,eax寄存器作为存放函数返回值使用 5: } 0040102E pop edi
原文:http://blog.csdn.net/itbuluoge/article/details/21991951