逆向冒泡算法

冒泡算法,以前学C的时候看到这名字就觉得深奥不敢看。。。。
C源代码:
main() 
{ 
   int i,j,temp; 
   int a[5];
   for(i=0;i<5;i++) 
   scanf ("%d,",&a[i]); //输入5个数
   for(i=0;i<=4;i++) 
   { 
    for (j=0;j<5-i;j++) 
     if (a[j]>a[j+1]) 
     { 
      temp=a[j]; 
      a[j]=a[j+1]; 
      a[j+1]=temp;
     } 
   }

   for(i=0;i<5;i++) 
   printf("%5d,",a[i] );
   printf("\n"); 
}


 
老做法!F8单步到跑飞CALL断下重新加载进Call分析!(好一个从句!)
 
 00401000       83EC 14               sub esp,14                               ; 14h=20,20=4*5
00401003       56                    push esi
00401004       57                    push edi                                 ; 保存现场
00401005       8D7424 08             lea esi,dword ptr ss:[esp+8]             ; 访问sub esp,14空出的缓冲区的首址
00401009       BF 05000000           mov edi,5                                ; edi=5
0040100E       56                    push esi                                 ; 把缓冲区用来接收数字(输入循环的开始)
0040100F       68 3C804000           push asm.0040803C                        ; ASCII "%d,"
00401014       E8 98000000           call asm.004010B1                        ; scanf
00401019       83C4 08               add esp,8                                ; 恢复两个单位的堆栈(以后我们就称4个字节为一个单位吧)
0040101C       83C6 04               add esi,4                                ; 指向缓冲区的指针加一个单位,即指向下一个元素
0040101F       4F                    dec edi                                  ; edi--;
00401020     ^ 75 EC                 jnz short asm.0040100E                   ; edi为0就退出循环(即初始化5个元素)(输入循环的结束)
00401022       BF 05000000           mov edi,5                                ; edi=5
00401027       85FF                  test edi,edi                             ; 大循环的开始(嵌套) 两个正整数相与,结果不为0所以Z为0  直到edi减小为0时或者本来就为0时这个操作才会导致Z=1 由于大循环结束处有cmp edi,1和jge跳转所以这里的jle循环算是废的了
00401029       7E 1A                 jle short asm.00401045                   ; 把它nop掉试试 ……结果运行也没错呵呵
0040102B       8D4424 0C             lea eax,dword ptr ss:[esp+C]             ; 缓冲区的第二个变量放在eax,也就是冒泡中所谓的a[j+1]了
0040102F       8BF7                  mov esi,edi                              ; 第一次循环的时候i和j相同都是5 只是在小循环里面j就是(esi)才递减了
00401031       8B48 FC               mov ecx,dword ptr ds:[eax-4]             ; 前一个变量(循环开始)
00401034       8B10                  mov edx,dword ptr ds:[eax]               ; 后一个变量
00401036       3BCA                  cmp ecx,edx                              ; 比较一下
00401038       7E 05                 jle short asm.0040103F                   ; 如果大于则调位(小于则不调位)
0040103A       8950 FC               mov dword ptr ds:[eax-4],edx
0040103D       8908                  mov dword ptr ds:[eax],ecx               ; 上面两句是调位代码
0040103F       83C0 04               add eax,4                                ; j++;
00401042       4E                    dec esi                                  ; 这里跟j++其实也差不多,只不过esi是用于计数,而没有用来寻址而已
00401043     ^ 75 EC                 jnz short asm.00401031                   ; 循环结束
00401045       4F                    dec edi
00401046       83FF 01               cmp edi,1
00401049     ^ 7D DC                 jge short asm.00401027                   ; 大循环的结束(嵌套)
0040104B       8D7424 08             lea esi,dword ptr ss:[esp+8]             ; 拿第一个数组元素
0040104F       BF 05000000           mov edi,5                                ; 输出5次吧
00401054       8B06                  mov eax,dword ptr ds:[esi]               ; 输出循环的开始
00401056       50                    push eax
00401057       68 34804000           push asm.00408034                        ; ASCII "%5d,"
0040105C       E8 1F000000           call asm.00401080
00401061       83C4 08               add esp,8
00401064       83C6 04               add esi,4
00401067       4F                    dec edi
00401068     ^ 75 EA                 jnz short asm.00401054                   ; 输出循环的结束
0040106A       68 30804000           push asm.00408030
0040106F       E8 0C000000           call asm.00401080                        ; printf
00401074       83C4 04               add esp,4                                ; 最后输出换行符
00401077       5F                    pop edi                                  ; 上面这些跟开头差不多了,只不过一个输入 一个输出罢了
00401078       5E                    pop esi
00401079       83C4 14               add esp,14
0040107C       C3                    retn
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值