阅读:1926回复:2
天书夜读的反汇编部分有一段代码不能理解,求救!
下面是发行版3*3矩阵相乘的反汇编。
int myfunction(int a[3][3],int b[3][3],int c[3][3]) { int i,j; for(i=0;i<3;i++) 00401000 mov eax,dword ptr [esp+4] ;a保存到 eax 中 00401004 mov edx,dword ptr [esp+0Ch] ;c保存到 edx 中 00401008 mov ecx,dword ptr [esp+8] ;b保存到ecx 中。 0040100C push ebx 0040100D push esi 0040100E add eax,4 ;这里已经开始处理数据。必须把这些指令和 ;函数入口指令和循环控制指令分开 00401011 push edi 00401012 add edx,8 ;同前面的add eax,4 00401015 mov esi,3 ;循环变量取3 0040101A lea ebx,[ebx] ;无意义指令 { for(j=0;j<3;j++) c[j] = a[0]*b[0][j]+a[1]*b[1][j]+a[2]*b[2][j]; 00401020 mov ebx,dword ptr [eax] ;显然从这里开始,是数值计算过程。代码的优化,使内部 00401022 imul ebx,dword ptr [ecx+0Ch] ;循环不见了。可以数一下imul 指令,刚好九次。可以说明 00401026 mov edi,dword ptr [ecx+18h] ;这里用一个单循环完成了原来双循环的工作。 00401029 imul edi,dword ptr [eax+4] 0040102D add edi,ebx 0040102F mov ebx,dword ptr [eax-4] 00401032 imul ebx,dword ptr [ecx] 00401035 add edi,ebx 00401037 mov dword ptr [edx-8],edi 0040103A mov ebx,dword ptr [eax] 0040103C imul ebx,dword ptr [ecx+10h] 00401040 mov edi,dword ptr [ecx+1Ch] 00401043 imul edi,dword ptr [eax+4] 00401047 add edi,ebx 00401049 mov ebx,dword ptr [eax-4] 0040104C imul ebx,dword ptr [ecx+4] 00401050 add edi,ebx 00401052 mov dword ptr [edx-4],edi 00401055 mov ebx,dword ptr [eax+4] 00401058 imul ebx,dword ptr [ecx+20h] 0040105C mov edi,dword ptr [ecx+14h] 0040105F imul edi,dword ptr [eax] 00401062 add edi,ebx 00401064 mov ebx,dword ptr [eax-4] 00401067 imul ebx,dword ptr [ecx+8] 0040106B add edi,ebx 0040106D mov dword ptr [edx],edi 0040106F add eax,0Ch 00401072 add edx,0Ch 00401075 dec esi ;这里开始两条,是循环指令 00401076 jne myfunction+20h (401020h) 00401078 pop edi 00401079 pop esi } return 0; 0040107A xor eax,eax 0040107C pop ebx } 0040100E add eax,4 这行就不能理解了,为什么要把eax加4? eax不是已经是传入参数的首地址了啊?同样edx加8也不能理解。 看了好多遍,始终不能明白。 |
|
沙发#
发布于:2008-11-26 12:39
00401000 mov eax,dword ptr [esp+4] ;a保存到 eax 中 , 此时 eax==a[0][0]
add eax, 4 ; 此时 eax == a[0][1] 不知道我理解是对不对 |
|
板凳#
发布于:2008-12-02 22:18
这个应该是编译器自己的做法吧,至于为什么这取决于编译器作者,也许有他认为合理的理由
暂时可以不必细究这个问题, 开始eax是指向a首地址了,加了4就指向a[0][1]了 后面的edx+8也是(指向c[0][2]),这应该是因编译器而异的做法吧 |
|