再次主要讨论或者验证三点:
1、循环结构的反汇编代码分析
2、函数中,局部变量的保存位置
3、方法的返回值保存位置验证
一个没有找到答案的疑问:
00401029 lea edi,[ebp-48h]
0040102C mov ecx,12h
00401031 mov eax,0CCCCCCCCh
;这段代码是在栈中开辟一个48字节大小的区域来存放局部变量,但是如果函数内
没有局部变量,则是lea edi,[ebp-40h]
一个局部变量,则是lea edi,[ebp-44h]
两个局部变量,则是lea edi,[ebp-48h]
也就是没有局部变量时开辟的40个字节,我用F11追踪过,单步调试时,这一部分区域并没有用到,这一区域的作用是什么?
代码如下:
1
int sum()
2
{
3
int subResult=0;
4
for (int i=0;i<3;i++)
5
{
6
subResult+=1;
7
}
8
return subResult;
9
}
10
11
void main()
12
{
13
int result = sum();
14
printf("%\d\n",result);
15
}
由于方法的调用已经在上一篇中说过,这里直接分析内部有循环结构的sum()方法
反汇编代码及分析:
5: int sum()
6: {
00401020 push ebp
;ESP = 0012FEF0 EBP = 0012FF48
00401021 mov ebp,esp
;ESP = 0012FEF0 EBP = 0012FEF0
00401023 sub esp,48h
;ESP = 0012FEA8 EBP = 0012FEF0
00401026 push ebx
00401027 push esi
00401028 push edi
00401029 lea edi,[ebp-48h]
0040102C mov ecx,12h
00401031 mov eax,0CCCCCCCCh
00401036 rep stos dword ptr [edi]
7: int subResult=0;
00401038 mov dword ptr [ebp-4],0
8: for (int i=0;i<3;i++)
0040103F mov dword ptr [ebp-8],0
;[ebp-4]=[0012FEEC]处存放的即是局部变量subResult的位置
;[ebp-8]=[0012FEE8]处存放的即是局部变量i的位置
;参看下图可知;subResult和i的初值均为000401046 jmp sum+31h (00401051)
;转到地址00401051(下方蓝字)处去判断循环条件是否满足(请从00401051处接着往下看)00401048 mov eax,dword ptr [ebp-8]
;将循环条件即i的值复制给eax0040104B add eax,1
;循环条件修正0040104E mov dword ptr [ebp-8],eax
;保存修正后的循环条件00401051 cmp dword ptr [ebp-8],3
00401055 jge sum+42h (00401062)
;比较dword ptr [ebp-8]处的值,即局部变量i的值与3的大小,如果小于3,则往下执行;如果大于等于3,则跳转到00401062处执行
;jge 指令 如果大于或等于则转移
9: {
10: subResult+=1;
00401057 mov ecx,dword ptr [ebp-4]
;将dword ptr [ebp-4]处的值即subResult的值传个寄存器ecx0040105A add ecx,1
;通过寄存器ecx实现循环加1操作0040105D mov dword ptr [ebp-4],ecx
;将加1后的值复制给dword ptr [ebp-4]处
11: }
00401060 jmp sum+28h (00401048)
;转移到00401048处,去进行下一轮的循环变量修正和判断12: return subResult;
00401062 mov eax,dword ptr [ebp-4]
;将最终的结果复制给eax,由此可以验证,函数的返回值保存在寄存器eax中
;为了更好的说明这一点,看下边main函数中sum函数的返回值的传递情况:
13: }
00401065 pop edi
00401066 pop esi
00401067 pop ebx
00401068 mov esp,ebp
0040106A pop ebp
0040106B ret