能力值:
( LV2,RANK:10 )
|
-
-
2 楼
从你的C源代码里看,最终返回的应该是d=0呀..
int i = 1;
int c = 0;
while (c < 100)
{
c = c+i; //当离开此循环时,c = 100
}
switch (c) //c = 100
{
case 0: //跳过
d = 1 ;
case 1: //跳过
d = c;
break;
default: //执行这部分语句,使得d = 0
d = 0;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
汇编代码我还没看,但另外C源代码里也是不可能有d=1的,假设你的while条件打错了,程序在switch进入case 0,则
case 0:
d = 1 ;
case 1:
d = c;
break;
由于case 0里没有break,因此在执行完d=1后会继续进入case 1执行d=c的语句,然后通过break离开这个switch
由于还没看上边的汇编,不知道是不是你的C代码打错的原因
刚看了汇编部分,发现确实同C代码一样。既然如此这个函数无论传入的a和b是什么,最终返回的d必然为0
附上汇编代码:
00413570 push ebp
00413571 mov ebp,esp
00413573 sub esp,0E8h
00413579 push ebx
0041357A push esi
0041357B push edi
0041357C lea edi,[ebp-0E8h]
00413582 mov ecx,3Ah
00413587 mov eax,0CCCCCCCCh
0041358C rep stos dword ptr es:[edi] ;前边都不看了,无关逻辑,从下边一行开始
0041358E mov eax,dword ptr [a] ;把a的值放入eax
00413591 add eax,dword ptr ;把b的值同eax中的值相加,即实现a+b
00413594 mov dword ptr [d],eax ;把eax的值送到d中,即实现d = a + b
00413597 mov dword ptr [i],1 ;把1送入i,即i = 1
0041359E mov dword ptr [c],0 ;同上,c = 0
004135A5 cmp dword ptr [c],64h ;cmp是一个比较语句,将c和64h进行比较(64h即为十六进制数的64,对应十进制数的100)
004135A9 jge myfunction+46h (4135B6h) ;在上一行比较后的跳转语句,jge为大于等于时跳转,这两行结合起来即为当c>=100时进行跳转,即while(c < 100)
004135AB mov eax,dword ptr [c] ;将c的值送入eax中
004135AE add eax,dword ptr [i] ;将i的值与eax中的值相加,即实现c + i
004135B1 mov dword ptr [c],eax ;将eax的值送入c,这三行即实现c = c + i
004135B4 jmp myfunction+35h (4135A5h) ;jmp为无条件跳转语句,相当于高级语言里的goto,这里跳转到4135A5这行也就是上边cmp比较语句的这行,从4135A5到这一行就是整个的while语句
004135B6 mov eax,dword ptr [c] ;把c送入eax
004135B9 mov dword ptr [ebp-0E8h],eax ;eax送入一块地址为ebp-0E8h的内存中
004135BF cmp dword ptr [ebp-0E8h],0 ;将ebp-0E8h里的值同0进行比较,即将c同0比较
004135C6 je myfunction+63h (4135D3h) ;je为若比较结果相等则跳转,此两行即为case 0
004135C8 cmp dword ptr [ebp-0E8h],1 ;将ebp-0E8h里的值同1进行比较,即将c同1比较
004135CF je myfunction+6Ah (4135DAh) ;je为若比较结果相等则跳转,此两行即为case 1
004135D1 jmp myfunction+72h (4135E2h) ;若上述两个case都不符合,即c既不等于0也不等于1,则进入default,在此处即为向default跳转
004135D3 mov dword ptr [d],1 ;此处即为case 0跳转来的位置,将1送入d中,即实现d = 1
004135DA mov eax,dword ptr [c] ;此处即为case 1跳转来的位置,同时也是case 0里的d = 1执行完后的下一条语句(由于case 0没有break,因此执行完case 0后进入case 1)。这一行的作用是将c送入eax中
004135DD mov dword ptr [d],eax ;将eax的值送入d中,结合上一行,这两行实现了d = c
004135E0 jmp myfunction+79h (4135E9h) ;跳转至4135E9,即这个switch的出口,这一行就是case 1里的break
004135E2 mov dword ptr [d],0 ;此处是default跳转来的位置,将0送入d中,即实现d = 0
004135E9 mov eax,dword ptr [d] ;这里是整个switch的出口,将d送入eax中
004135EC pop edi ;edi出栈,以下几行同开头几行一样无关逻辑,咱们就不分析了
004135ED pop esi
004135EE pop ebx
004135EF mov esp,ebp
004135F1 pop ebp
004135F2 ret ;ret(或retn)即为一个调用的返回,即一个子程序或函数的出口
刚到看雪论坛不久,也不知道怎么能把帖子编辑的整齐一些,各位凑合着看吧,不好意思了。其实这会儿也是闲着,因为不知道楼主对相关知识掌握的如何,所以写写这些注释,要是有什么地方冒犯了还请别见怪~注释的这些也只是我个人理解~
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
呵呵,肯定就是少打了一个break造成的。汇编代码里的顺序也很清楚。对比一下:
case 0:
d = 1 ; //对应 004135D3 mov dword ptr [d],1
//这里没有break,程序继续向下执行
case 1:
d = c; //对应 004135DA mov eax,dword ptr [c]
//和 004135DD mov dword ptr [d],eax
break; //中断执行,退出swtich
//对应 004135E0 jmp myfunction+79h (4135E9h)
如果源程序在case 0的代码部分增加一条break的话,在
004135D3 mov dword ptr [d],1
这一句后面会多出一条语句
004135E0 jmp myfunction+79h (4135E9h)
当然了,不会再是+79h,而是+7Bh(上面一句也同样会变成+7Bh)。
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
太感谢两个兄弟了 明白了
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
解决了。。。
|