一个简单程序的反编译

看了老赵的博客从汇编入手,探究泛型的性能问题 ,突然想起以前自己写过一个关于反汇编的文章,特转过来。

 源代码如下:

 

void  main(){

int  a[ 3 ][ 3 ] = {{ 1 , 1 , 1 },{ 2 , 2 , 2 },{ 3 , 3 , 3 }};
int  b[ 3 ][ 3 ] = {{ 3 , 3 , 3 },{ 2 , 2 , 2 },{ 1 , 1 , 1 }};
int  c[ 3 ][ 3 ];
myfunction(a,b,c);
}

/* 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 ++ )
{
for (j = 0 ;j < 3 ;j ++ )
{
c[i][j]
= a[i][ 0 ] * b[ 0 ][j] + a[i][ 1 ] * b[ 1 ][j] + a[i][ 2 ] * b[ 2 ][j];
printf(
" %d  " ,c[i][j]);
}
}
return   0 ;
}

 

 

在我的机器上,32VS2008+32VISTA汇编是,此时是debug未优化模式:

 

013810D0  /$  55   push  ebp 
013810D1  . 8BEC  mov  ebp, esp 
013810D3  . 83EC 6C  sub  esp, 6C
013810D6  . C745 DC  01000 > mov  dword ptr [ebp- 24 ],  1
013810DD  . C745 E0  01000 > mov  dword ptr [ebp- 20 ],  1
013810E4  . C745 E4  01000 > mov  dword ptr [ebp-1C],  1
013810EB  . C745 E8  02000 > mov  dword ptr [ebp- 18 ],  2
013810F2  . C745 EC  02000 > mov  dword ptr [ebp- 14 ],  2
013810F9  . C745 F0  02000 > mov  dword ptr [ebp- 10 ],  2
01381100  . C745 F4  03000 > mov  dword ptr [ebp-C],  3
01381107  . C745 F8  03000 > mov  dword ptr [ebp- 8 ],  3
0138110E  . C745 FC  03000 > mov  dword ptr [ebp- 4 ],  3 ;初始化数组a
01381115  . C745 B8  03000 > mov  dword ptr [ebp- 48 ],  3
0138111C  . C745 BC  03000 > mov  dword ptr [ebp- 44 ],  3
01381123  . C745 C0  03000 > mov  dword ptr [ebp- 40 ],  3
0138112A  . C745 C4  02000 > mov  dword ptr [ebp-3C],  2
01381131  . C745 C8  02000 > mov  dword ptr [ebp- 38 ],  2
01381138  . C745 CC  02000 > mov  dword ptr [ebp- 34 ],  2
0138113F  . C745 D0  01000 > mov  dword ptr [ebp- 30 ],  1
01381146  . C745 D4  01000 > mov  dword ptr [ebp-2C],  1
0138114D  . C745 D8  01000 > mov  dword ptr [ebp- 28 ],  1 ;初始化数组b
01381154  . 8D45  94   lea  eax, dword ptr [ebp-6C]
01381157  .  50   push  eax;压入数组c的首地址
01381158  . 8D4D B8  lea  ecx, dword ptr [ebp- 48 ]
0138115B  .  51   push  ecx;压入数组b的首地址
0138115C  . 8D55 DC  lea  edx, dword ptr [ebp- 24 ]
0138115F  .  52   push  edx;压入数组a的首地址
01381160  . E8 9BFEFFFF  call   01381000 ;调用函数myfunction
01381165  . 83C4  0C   add  esp,  0C
01381168  . 33C0  xor  eax, eax
0138116A  . 8BE5  mov  esp, ebp
0138116C  . 5D  pop  ebp
0138116D  \. C3  retn

 

 

 


进入函数myfunction

 

01381000  /$  55   push  ebp
01381001  . 8BEC  mov  ebp, esp
01381003  . 83EC  08   sub  esp,  8
01381006  .  56   push  esi
01381007  .  57   push  edi
01381008  . C745 FC  00000 > mov  dword ptr [ebp- 4 ],  0 ;i= 0
0138100F  . EB  09   jmp  short  0138101A
01381011  > 8B45 FC / mov  eax, dword ptr [ebp- 4 ]
01381014  . 83C0  01   add  eax,  1 ;i++
01381017  .  8945  FC  mov  dword ptr [ebp- 4 ], eax
0138101A  > 837D FC  03   cmp  dword ptr [ebp- 4 ],  3 ;i< 3
0138101E  .  0F8D   99000000   jge   013810BD
01381024  . C745 F8  00000 > mov  dword ptr [ebp- 8 ],  0 ; j=0
0138102B  . EB  09   jmp  short  01381036
0138102D  > 8B4D F8 / mov  ecx, dword ptr [ebp- 8 ]
01381030  . 83C1  01   add  ecx,  1 ; j++
01381033  . 894D F8  mov  dword ptr [ebp- 8 ], ecx
01381036  > 837D F8  03   cmp  dword ptr [ebp- 8 ],  3 ; j<3
0138103A  . 7D 7C  jge  short  013810B8
0138103C  . 8B55 FC  mov  edx, dword ptr [ebp- 4 ; 取i值
0138103F  . 6BD2  0C   imul  edx, edx,  0C ;计算a[i][ 0 ]的偏移量
01381042  . 8B45  08   mov  eax, dword ptr [ebp+ 8 ];取a的首地址
01381045  . 8B4D F8  mov  ecx, dword ptr [ebp- 8 ];取j值
01381048  . 8B75  0C   mov  esi, dword ptr [ebp+C];取b的首地址
0138104B  . 8B1410  mov  edx, dword ptr [eax+edx];取a[i][ 0 ] 的值,首地址加偏移
0138104E  .  0FAF148E   imul  edx, dword ptr [esi+ecx* 4 ];取b[ 0 ][j]的值,并将 a[i][ 0 ]*b[ 0 ][j]的计算结果存入edx
01381052  . 8B45 FC  mov  eax, dword ptr [ebp- 4 ]
01381055  . 6BC0  0C   imul  eax, eax,  0C
01381058  . 8B4D  08   mov  ecx, dword ptr [ebp+ 8 ]
0138105B  . 8B75 F8  mov  esi, dword ptr [ebp- 8 ]
0138105E  . 8B7D  0C   mov  edi, dword ptr [ebp+C]
01381061  . 8B4401  04   mov  eax, dword ptr [ecx+eax+ 4 ];取a[i][ 1 ]的值,偏移+ 4
01381065  .  0FAF44B7   0C   imul  eax, dword ptr [edi+esi* 4 +C]取b[ 1 ][j]的值,偏移+ 12 ,结果存eax
0138106A  .  03D0   add  edx, eax;计算前两步加法结果
0138106C  . 8B4D FC  mov  ecx, dword ptr [ebp- 4 ]
0138106F  . 6BC9  0C   imul  ecx, ecx,  0C
01381072  . 8B45  08   mov  eax, dword ptr [ebp+ 8 ]
01381075  . 8B75 F8  mov  esi, dword ptr [ebp- 8 ]
01381078  . 8B7D  0C   mov  edi, dword ptr [ebp+C]
0138107B  . 8B4C08  08   mov  ecx, dword ptr [eax+ecx+ 8 ];取a[i][ 2 ]
0138107F  .  0FAF4CB7   18   imul  ecx, dword ptr [edi+esi* 4 + 18 ]取a[ 2 ][j],计算第3个乘法
01381084  .  03D1   add  edx, ecx;循环一次的最终计算结果存在edx
01381086  . 8B45 FC  mov  eax, dword ptr [ebp- 4 ]
01381089  . 6BC0  0C   imul  eax, eax,  0C
0138108C  .  0345   10   add  eax, dword ptr [ebp+ 10 ];取c的首地址
0138108F  . 8B4D F8  mov  ecx, dword ptr [ebp- 8 ]
01381092  .  891488   mov  dword ptr [eax+ecx* 4 ], edx赋值给c[i][j]
01381095  . 8B55 FC  mov  edx, dword ptr [ebp- 4 ]
01381098  . 6BD2  0C   imul  edx, edx,  0C
0138109B  .  0355   10   add  edx, dword ptr [ebp+ 10 ]
0138109E  . 8B45 F8  mov  eax, dword ptr [ebp- 8 ]
013810A1  . 8B0C82  mov  ecx, dword ptr [edx+eax* 4 ];取出c[i][j],准备printf()
013810A4  .  51   push  ecx  ;  /<%d>
013810A5  .  68  F4203801  push   013820F4   ;  format = "%d "
013810AA  . FF15 A0203801  call  dword ptr [<&MSVCR90.printf>]  ;  \printf
013810B0  . 83C4  08   add  esp,  8
013810B3  .^ E9 75FFFFFF \ jmp   0138102D
013810B8  >^ E9 54FFFFFF \ jmp   01381011
013810BD  > 33C0  xor  eax, eax
013810BF  . 5F  pop  edi
013810C0  . 5E  pop  esi
013810C1  . 8BE5  mov  esp, ebp
013810C3  . 5D  pop  ebp
013810C4  \. C3  retn

 

 

比较容易就能看懂,下面是MAXIMIZE SPEED优化:

 

ContractedBlock.gif ExpandedBlockStart.gif main--maxspeed
01391080 /$ 83EC 6C sub esp, 6C
01391083 . BA 01000000 mov edx, 1
01391088 . B9 02000000 mov ecx, 2
0139108D . B8 03000000 mov eax, 3
01391092 . 895424 24 mov dword ptr [esp+24], edx
01391096 . 895424 28 mov dword ptr [esp+28], edx
0139109A . 895424 2C mov dword ptr [esp+2C], edx
0139109E . 894C24 30 mov dword ptr [esp+30], ecx
013910A2 . 894C24 34 mov dword ptr [esp+34], ecx
013910A6 . 894C24 38 mov dword ptr [esp+38], ecx
013910AA . 894424 3C mov dword ptr [esp+3C], eax
013910AE . 894424 40 mov dword ptr [esp+40], eax
013910B2 . 894424 44 mov dword ptr [esp+44], eax
013910B6 . 890424 mov dword ptr [esp], eax
013910B9 . 894424 04 mov dword ptr [esp+4], eax
013910BD . 894424 08 mov dword ptr [esp+8], eax
013910C1 . 894C24 0C mov dword ptr [esp+C], ecx
013910C5 . 894C24 10 mov dword ptr [esp+10], ecx
013910C9 . 894C24 14 mov dword ptr [esp+14], ecx
013910CD . 895424 18 mov dword ptr [esp+18], edx
013910D1 . 895424 1C mov dword ptr [esp+1C], edx
013910D5 . 895424 20 mov dword ptr [esp+20], edx
013910D9 . 8D4C24 48 lea ecx, dword ptr [esp+48];数组c
013910DD . 8D0424 lea eax, dword ptr [esp]; 数组b
013910E0 . 8D5424 24 lea edx, dword ptr [esp+24];数组a
013910E4 . E8 17FFFFFF call 01391000
013910E9 . 33C0 xor eax, eax
013910EB . 83C4 6C add esp, 6C
013910EE \. C3 retn

 

 

同样,初始化数组,只不过是改用了寄存器初始化,同样在初始化完成后压入数组的首地址

 

ContractedBlock.gif ExpandedBlockStart.gif myFunction--maxspeed
01391000 /$ 83EC 08 sub esp, 8
01391003 . 53 push ebx
01391004 . 55 push ebp
01391005 . 56 push esi
01391006 . 57 push edi
01391007 . 83C0 0C add eax, 0C;将数组b地址+12,挪到b[1][0]的位置
0139100A . 8BFA mov edi, edx
0139100C . 894424 14 mov dword ptr [esp+14], eax;将b[1][0]位置记录下来
01391010 . 8BD9 mov ebx, ecx
01391012 . 83C7 04 add edi, 4;数组a挪到a[0][1]的位置
01391015 . C74424 10 030>mov dword ptr [esp+10], 3记录i
0139101D . 8D49 00 lea ecx, dword ptr [ecx];??
01391020 > 8B7424 14 /mov esi, dword ptr [esp+14]
01391024 . BD 03000000 mov ebp, 3;记录j
01391029 . 8DA424 000000>lea esp, dword ptr [esp]
01391030 > 8B4E F4 /mov ecx, dword ptr [esi-C];取b[0][j]
01391033 . 8B56 0C mov edx, dword ptr [esi+C];取b[2][j]
01391036 . 0FAF4F FC imul ecx, dword ptr [edi-4];取a[i][0],第1段乘法
0139103A . 0FAF57 04 imul edx, dword ptr [edi+4];取a[i][2],第3段乘法
0139103E . 8B06 mov eax, dword ptr [esi];取b[1][j]
01391040 . 0FAF07 imul eax, dword ptr [edi];取a[i][1],第2段乘法
01391043 . 03CA add ecx, edx
01391045 . 03C1 add eax, ecx;结果放在eax中
01391047 . 50 push eax ; /<%d>
01391048 . 68 F4203901 push 013920F4 ; format = "%d "
0139104D . 8903 mov dword ptr [ebx], eax ; 写入到c[i][j]中
0139104F . FF15 A0203901 call dword ptr [<&MSVCR90.printf>] ; \printf
01391055 . 83C4 08 add esp, 8
01391058 . 83C6 04 add esi, 4;j++
0139105B . 83C3 04 add ebx, 4;挪到c[i][j+1]
0139105E . 83ED 01 sub ebp, 1;j<3
01391061 .^ 75 CD \jnz short 01391030
01391063 . 83C7 0C add edi, 0C;i++
01391066 . 836C24 10 01 sub dword ptr [esp+10], 1;i<3
0139106B .^ 75 B3 \jnz short 01391020
0139106D . 5F pop edi
0139106E . 5E pop esi
0139106F . 5D pop ebp
01391070 . 33C0 xor eax, eax
01391072 . 5B pop ebx
01391073 . 83C4 08 add esp, 8
01391076 \. C3 retn

 

最后是MININIZE SIZE模式:

这个模式下直接合并(还是 应该叫内联)了main和myFunction子函数。

 

00ED1000  /$  55   push  ebp
00ED1001  . 8BEC  mov  ebp, esp
00ED1003  . 83EC 7C  sub  esp, 7C
00ED1006  .  53   push  ebx
00ED1007  .  56   push  esi
00ED1008  .  57   push  edi
00ED1009  . 6A  02   push   2
00ED100B  .  58   pop  eax
00ED100C  . 33C9  xor  ecx, ecx
00ED100E  .  41   inc  ecx
00ED100F  . 6A  03   push   3
00ED1011  . 5E  pop  esi  ;  j<3
00ED1012  . 894D A8  mov  dword ptr [ebp- 58 ], ecx
00ED1015  . 894D AC  mov  dword ptr [ebp- 54 ], ecx
00ED1018  . 894D B0  mov  dword ptr [ebp- 50 ], ecx
00ED101B  . 894D E4  mov  dword ptr [ebp-1C], ecx
00ED101E  . 894D E8  mov  dword ptr [ebp- 18 ], ecx
00ED1021  . 894D EC  mov  dword ptr [ebp- 14 ], ecx
00ED1024  . 33C9  xor  ecx, ecx
00ED1026  .  8945  B4  mov  dword ptr [ebp-4C], eax
00ED1029  .  8945  B8  mov  dword ptr [ebp- 48 ], eax
00ED102C  .  8945  BC  mov  dword ptr [ebp- 44 ], eax
00ED102F  .  8975  C0  mov  dword ptr [ebp- 40 ], esi
00ED1032  .  8975  C4  mov  dword ptr [ebp-3C], esi
00ED1035  .  8975  C8  mov  dword ptr [ebp- 38 ], esi
00ED1038  .  8975  CC  mov  dword ptr [ebp- 34 ], esi
00ED103B  .  8975  D0  mov  dword ptr [ebp- 30 ], esi
00ED103E  .  8975  D4  mov  dword ptr [ebp-2C], esi
00ED1041  .  8945  D8  mov  dword ptr [ebp- 28 ], eax
00ED1044  .  8945  DC  mov  dword ptr [ebp- 24 ], eax
00ED1047  .  8945  E0  mov  dword ptr [ebp- 20 ], eax
00ED104A  . 894D FC  mov  dword ptr [ebp- 4 ], ecx  ;  i=0
00ED104D  . EB  03   jmp  short  00ED1052
00ED104F  > 8B4D FC / mov  ecx, dword ptr [ebp- 4 ]
00ED1052  > 8D440D AC  lea  eax, dword ptr [ebp+ecx- 54 ;  a[i][1]的地址
00ED1056  . 8B50  04   mov  edx, dword ptr [eax+ 4 ;  a[i][2]
00ED1059  .  8955  F4  mov  dword ptr [ebp-C], edx  ;  a[i][2]=>[ebp-C]
00ED105C  . 8B10  mov  edx, dword ptr [eax]  ;  a[i][1]
00ED105E  . 8B40 FC  mov  eax, dword ptr [eax- 4 ;  a[i][0]
00ED1061  . 33DB  xor  ebx, ebx  ;  j=0
00ED1063  .  8955  F0  mov  dword ptr [ebp- 10 ], edx  ;  a[i][1]=>[ebp-10]
00ED1066  .  8945  F8  mov  dword ptr [ebp- 8 ], eax  ;  a[i][0]=>[ebp-8]
00ED1069  . 8D7C0D  84   lea  edi, dword ptr [ebp+ecx-7C]
00ED106D  > 8B449D CC / mov  eax, dword ptr [ebp+ebx* 4 - 34 ;  b[0][j]
00ED1071  .  0FAF45  F8  imul  eax, dword ptr [ebp- 8 ;  a[i][0]*b[0][j]
00ED1075  . 8B4C9D E4  mov  ecx, dword ptr [ebp+ebx* 4 -1C]  ;  b[2][j]
00ED1079  .  0FAF4D  F4  imul  ecx, dword ptr [ebp-C]  ;  a[i][2]*b[2][j]
00ED107D  .  03C1   add  eax, ecx
00ED107F  . 8B4C9D D8  mov  ecx, dword ptr [ebp+ebx* 4 - 28 ;  b[1][j]
00ED1083  .  0FAF4D  F0  imul  ecx, dword ptr [ebp- 10 ;  a[i][1]*b[1][j]
00ED1087  .  03C1   add  eax, ecx  ;  最后结果
00ED1089  .  50   push  eax  ;  /<%d>
00ED108A  .  68  F420ED00  push   00ED20F4   ;  format = "%d "
00ED108F  . FF15 A020ED00  call  dword ptr [<&MSVCR90.printf>]  ;  \printf
00ED1095  .  43   inc  ebx  ;  j++
00ED1096  .  59   pop  ecx
00ED1097  . 83C7  04   add  edi,  4
00ED109A  . 3BDE  cmp  ebx, esi
00ED109C  .  59   pop  ecx
00ED109D  .^ 7C CE \ jl  short  00ED106D
00ED109F  .  8345  FC  0C   add  dword ptr [ebp- 4 ],  0C   ;  i++
00ED10A3  . 837D FC  24   cmp  dword ptr [ebp- 4 ],  24   ;  i<3
00ED10A7  .^ 7C A6 \ jl  short  00ED104F
00ED10A9  . 5F  pop  edi
00ED10AA  . 5E  pop  esi
00ED10AB  . 33C0  xor  eax, eax
00ED10AD  . 5B  pop  ebx
00ED10AE  . C9  leave
00ED10AF  \. C3  retn

 


 

后记:未优化模式就是原生代码,其调式期间可以和源代码一 一对应,maxspeed模式则尽可能将操作放在寄存器内完成,并且有一定的算法优化;而最小代码模式则通过合并部分代码,尽可能的通过EBP比例变址寻址,完成对二维数组的访问。

PS:本人汇编水平不高,如果有错误的地方欢迎指出斧正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值