逆向分析之LSD基数排序 ;逆向之循环数组队列

来源:互联网 发布:阻抗匹配网络 编辑:程序博客网 时间:2024/04/30 04:57

逆向分析之LSD基数排序 


版本:Release

优化选项:O2
调试工具:OD
源码:
[cpp] view plaincopyprint?
  1. //LSD基数排序(桶排序,模拟队列实现)   
  2. #include <stdio.h>   
  3. #include <stdlib.h>   
  4. #include <time.h>   
  5.   
  6. #define MAX_SIZE 11 //PS:set nodes number   
  7.   
  8. void listsort(int a[],int link[],int n,int first);  
  9.   
  10. int digit(int a,int i,int r)  
  11. {  
  12.     int n=2-i;  
  13.     while(n>0&&(a/=r))  
  14.         n--;  
  15.     a%=10;  
  16.     return a;  
  17. }  
  18.   
  19. int radixsort(int a[],int link[],int d,int r,int n)  
  20. {  
  21.     int i,last,first=1,bin,current;  
  22.     int front[10],rear[10];//10个桶  
  23.     for(i=1;i<n;i++)  
  24.         link[i]=i+1;  
  25.     link[n]=0;  
  26.     for(i=d-1;i>=0;i--)//对相应位排序入桶  
  27.     {  
  28.         for(bin=0;bin<r;bin++)  
  29.         {  
  30.             front[bin]=0;  
  31.             rear[bin]=0;  
  32.         }  
  33.         for(current=first;current;current=link[current])  
  34.         {  
  35.             bin=digit(a[current],i,r);//取相应位的数字  
  36.             if(front[bin]==0)  
  37.                 front[bin]=current;  
  38.             else  
  39.                 link[rear[bin]]=current;  
  40.             rear[bin]=current;  
  41.         }  
  42.         for(bin=0;!front[bin];bin++)  
  43.             ;  
  44.         first=front[bin];  
  45.         last=rear[bin];  
  46.         for(bin++;bin<r;bin++)//将各桶连接  
  47.             if(front[bin])  
  48.             {  
  49.                 link[last]=front[bin];  
  50.                 last=rear[bin];  
  51.             }  
  52.         link[last]=0;  
  53.     }  
  54.     return first;  
  55. }  
  56.   
  57. int main()  
  58. {  
  59.     int i,first,current;  
  60.     int a[MAX_SIZE];  
  61.     int link[MAX_SIZE];  
  62.     srand((unsigned)time(0));  
  63.     for(i=1;i<MAX_SIZE;i++)  
  64.         a[i]=rand()%1000;  
  65.     for(i=1;i<MAX_SIZE;i++)  
  66.         printf("%4d",a[i]);  
  67.     putchar('\n');  
  68.     first=radixsort(a,link,3,10,10);  
  69.     for(current=first;current;current=link[current])  
  70.         printf("%4d",a[current]);  
  71. /* 
  72.     listsort(a,link,MAX_SIZE,first); 
  73.     for(i=1;i<MAX_SIZE;i++) 
  74.         printf("%4d",a[i]); 
  75. 链表记录重放*/  
  76.     system("pause");  
  77.     return 0;  
  78. }  
  79. /* 
  80. void listsort(int a[],int link[],int n,int first)//链表记录重放 
  81. { 
  82.     int q,i,temp; 
  83.     for(i=1;i<n;i++) 
  84.     { 
  85.         while(first<i) first=link[first]; 
  86.         q=link[first]; 
  87.         if(first!=n) 
  88.         { 
  89.             SWAP(a[i],a[first],temp); 
  90.             link[first]=link[i]; 
  91.             link[i]=first; 
  92.         } 
  93.         first=q; 
  94.     } 
  95. } 
  96. */  
  97.   
  98. 主函数就不贴了,很简单  
  99. 这里贴上主要的排序函数,在下面的代码中假设不知道源码的情况下,我假设了4个int [10]大小的数组,其中2个是参数a[10],b[10],2个是函数内的局部变量c[10],d[10]  
  100. 01231000 >/$  83EC 50       sub     esp, 50                           ;  此时eax中存放着待排序数组a[10],ebx存放另一个数组b[10]  
  101. 01231003  |.  55            push    ebp  
  102. 01231004  |.  56            push    esi  
  103. 01231005  |.  33ED          xor     ebp, ebp  
  104. 01231007  |.  C743 04 02000>mov     dword ptr [ebx+4], 2              ;  初始化第二个数组  
  105. 0123100E  |.  C743 08 03000>mov     dword ptr [ebx+8], 3  
  106. 01231015  |.  C743 0C 04000>mov     dword ptr [ebx+C], 4  
  107. 0123101C  |.  C743 10 05000>mov     dword ptr [ebx+10], 5  
  108. 01231023  |.  C743 14 06000>mov     dword ptr [ebx+14], 6  
  109. 0123102A  |.  C743 18 07000>mov     dword ptr [ebx+18], 7  
  110. 01231031  |.  C743 1C 08000>mov     dword ptr [ebx+1C], 8  
  111. 01231038  |.  C743 20 09000>mov     dword ptr [ebx+20], 9  
  112. 0123103F  |.  C743 24 0A000>mov     dword ptr [ebx+24], 0A  
  113. 01231046  |.  57            push    edi  
  114. 01231047  |.  B8 01000000   mov     eax, 1  
  115. 0123104C  |.  896B 28       mov     dword ptr [ebx+28], ebp  
  116. 0123104F  |.  90            nop  
  117. 01231050  |>  33C9          /xor     ecx, ecx                         ;  这可是个大循环啊~~~先初始化所有的临时变量b[10],c[10]  
  118. 01231052  |.  894C24 34     |mov     dword ptr [esp+34], ecx  
  119. 01231056  |.  894C24 38     |mov     dword ptr [esp+38], ecx  
  120. 0123105A  |.  894C24 3C     |mov     dword ptr [esp+3C], ecx  
  121. 0123105E  |.  894C24 40     |mov     dword ptr [esp+40], ecx  
  122. 01231062  |.  894C24 44     |mov     dword ptr [esp+44], ecx  
  123. 01231066  |.  894C24 48     |mov     dword ptr [esp+48], ecx  
  124. 0123106A  |.  894C24 4C     |mov     dword ptr [esp+4C], ecx  
  125. 0123106E  |.  894C24 50     |mov     dword ptr [esp+50], ecx  
  126. 01231072  |.  894C24 54     |mov     dword ptr [esp+54], ecx  
  127. 01231076  |.  894C24 58     |mov     dword ptr [esp+58], ecx  
  128. 0123107A  |.  894C24 0C     |mov     dword ptr [esp+C], ecx  
  129. 0123107E  |.  894C24 10     |mov     dword ptr [esp+10], ecx  
  130. 01231082  |.  894C24 14     |mov     dword ptr [esp+14], ecx  
  131. 01231086  |.  894C24 18     |mov     dword ptr [esp+18], ecx  
  132. 0123108A  |.  894C24 1C     |mov     dword ptr [esp+1C], ecx  
  133. 0123108E  |.  894C24 20     |mov     dword ptr [esp+20], ecx  
  134. 01231092  |.  894C24 24     |mov     dword ptr [esp+24], ecx  
  135. 01231096  |.  894C24 28     |mov     dword ptr [esp+28], ecx  
  136. 0123109A  |.  894C24 2C     |mov     dword ptr [esp+2C], ecx  
  137. 0123109E  |.  894C24 30     |mov     dword ptr [esp+30], ecx  
  138. 012310A2  |.  8BF0          |mov     esi, eax  
  139. 012310A4  |.  85C0          |test    eax, eax  
  140. 012310A6  |.  74 67         |je      short 0123110F                            ;在下面这个循环凡是用到ebx的取内存数据都是类似b[ecx],凡是用到esp的都是取临时数组c[ecx]  d[ecx]此类  
  141. 012310A8  |.  EB 06         |jmp     short 012310B0  
  142. 012310AA  |   8D9B 00000000 |lea     ebx, dword ptr [ebx]  
  143. 012310B0  |>  8B4424 60     |/mov     eax, dword ptr [esp+60]         ;  传进来的参数,存的是待排序数组地址  
  144. 012310B4  |.  8B0CB0        ||mov     ecx, dword ptr [eax+esi*4]  
  145. 012310B7  |.  8BFD          ||mov     edi, ebp  
  146. 012310B9  |.  85ED          ||test    ebp, ebp  
  147. 012310BB  |.  7E 1B         ||jle     short 012310D8  
  148. 012310BD  |.  8D49 00       ||lea     ecx, dword ptr [ecx]  
  149. 012310C0  |>  B8 67666666   ||/mov     eax, 66666667                   ;下面几个是除法优化后的指令(ecx/10),如果不明白可以参考第一篇hash逆向,里面有更详细的解释  
  150. 012310C5  |.  F7E9          |||imul    ecx  
  151. 012310C7  |.  C1FA 02       |||sar     edx, 2  
  152. 012310CA  |.  8BCA          |||mov     ecx, edx  
  153. 012310CC  |.  C1E9 1F       |||shr     ecx, 1F  
  154. 012310CF  |.  03CA          |||add     ecx, edx                                    ;截至到这里就取得了除法的商  
  155. 012310D1  |.  74 05         |||je      short 012310D8  
  156. 012310D3  |.  4F            |||dec     edi  
  157. 012310D4  |.  85FF          |||test    edi, edi  
  158. 012310D6  |.^ 7F E8         ||\jg      short 012310C0  
  159. 012310D8  |>  B8 67666666   ||mov     eax, 66666667                    ;依然是除法优化,ecx/10  
  160. 012310DD  |.  F7E9          ||imul    ecx  
  161. 012310DF  |.  C1FA 02       ||sar     edx, 2  
  162. 012310E2  |.  8BC2          ||mov     eax, edx  
  163. 012310E4  |.  C1E8 1F       ||shr     eax, 1F  
  164. 012310E7  |.  03C2          ||add     eax, edx  
  165. 012310E9  |.  8D1480        ||lea     edx, dword ptr [eax+eax*4]  
  166. 012310EC  |.  03D2          ||add     edx, edx  
  167. 012310EE  |.  2BCA          ||sub     ecx, edx                        ;  这里应该是得到指定位数字的结果吧,前面先不管了看不懂这种优化。。  
  168. 012310F0  |.  837C8C 0C 00  ||cmp     dword ptr [esp+ecx*4+C], 0      ;  下面几句大体上是这样if(c[ecx]==0) c[ecx]=esi; else b[d[ecx]]=esi;  
  169. 012310F5  |.  75 06         ||jnz     short 012310FD  
  170. 012310F7  |.  89748C 0C     ||mov     dword ptr [esp+ecx*4+C], esi  
  171. 012310FB  |.  EB 07         ||jmp     short 01231104  
  172. 012310FD  |>  8B448C 34     ||mov     eax, dword ptr [esp+ecx*4+34]  
  173. 01231101  |.  893483        ||mov     dword ptr [ebx+eax*4], esi  
  174. 01231104  |>  89748C 34     ||mov     dword ptr [esp+ecx*4+34], esi  
  175. 01231108  |.  8B34B3        ||mov     esi, dword ptr [ebx+esi*4]  
  176. 0123110B  |.  85F6          ||test    esi, esi                        ;  这个比较大的循环里整体浏览下也可以发现esi是循环判断条件,但esi又牵扯到前面几个指令,其中又有我们暂时不知道干嘛的寄存器,于是可以先把架子写出来加上注释,等弄懂内部循环后再来修改也行  
  177. 0123110D  |.^ 75 A1         |\jnz     short 012310B0  
  178. 0123110F  |>  33C9          |xor     ecx, ecx  
  179. 01231111  |.  394C24 0C     |cmp     dword ptr [esp+C], ecx  
  180. 01231115  |.  75 08         |jnz     short 0123111F  
  181. 01231117  |>  41            |/inc     ecx  
  182. 01231118  |.  837C8C 0C 00  ||cmp     dword ptr [esp+ecx*4+C], 0  
  183. 0123111D  |.^ 74 F8         |\je      short 01231117  
  184. 0123111F  |>  8B448C 0C     |mov     eax, dword ptr [esp+ecx*4+C]  
  185. 01231123  |.  8B548C 34     |mov     edx, dword ptr [esp+ecx*4+34]  
  186. 01231127  |.  41            |inc     ecx  
  187. 01231128  |.  83F9 0A       |cmp     ecx, 0A  
  188. 0123112B  |.  7D 1B         |jge     short 01231148  
  189. 0123112D  |.  03C9          |add     ecx, ecx  
  190. 0123112F  |.  03C9          |add     ecx, ecx  
  191. 01231131  |>  8B7C0C 0C     |/mov     edi, dword ptr [esp+ecx+C]  
  192. 01231135  |.  85FF          ||test    edi, edi  
  193. 01231137  |.  74 07         ||je      short 01231140  
  194. 01231139  |.  893C93        ||mov     dword ptr [ebx+edx*4], edi  
  195. 0123113C  |.  8B540C 34     ||mov     edx, dword ptr [esp+ecx+34]  
  196. 01231140  |>  83C1 04       ||add     ecx, 4  
  197. 01231143  |.  83F9 28       ||cmp     ecx, 28  
  198. 01231146  |.^ 7C E9         |\jl      short 01231131  
  199. 01231148  |>  45            |inc     ebp  
  200. 01231149  |.  83FD 02       |cmp     ebp, 2                           ;  这里ebp为判断条件并且可以发现没有地方改变ebp的值,于是整个for框架可以直接写出来了  
  201. 0123114C  |.  C70493 000000>|mov     dword ptr [ebx+edx*4], 0  
  202. 01231153  |.^ 0F8E F7FEFFFF \jle     01231050  
  203. 01231159  |.  5F            pop     edi  
  204. 0123115A  |.  5E            pop     esi  
  205. 0123115B  |.  5D            pop     ebp  
  206. 0123115C  |.  83C4 50       add     esp, 50  
  207. 0123115F  \.  C3            retn  

注释不多,不过我想说说逆向这个函数的时候的我的方法
首先浏览下所有的跳转,清楚哪些跳转跳向哪里,然后观察一些条件判断用到的寄存器,回溯看看有没有在其他地方用到他而不用管他到底做了什么,如果只在判断处用到了的话最好了那么直接用个变量代替寄存器就能写出这个循环的整体架子,然后逐步深入,诸如if else类的跳转也可以先写出来而不用管其内部指令干了什么,就像造房子的时候先把它的架子给搞出来,之后内部再慢慢添砖加瓦,我们可以先对函数有个模糊的架子印象然后再去纠结这个函数到底做了什么
我以前也干过像把寄存器记在纸上逐条翻译指令最后再整理出结果这样纯粹蛮力的逆向一个函数,至于怎样做更效率更准确我也不好说,只能说我个人觉得有技巧性的逆向更好,学到的也更多
下面我再把边逆向边还原出的代码贴上来,应该也能看出点门道吧嗯~~~~~
[cpp] view plaincopyprint?
  1. int eax=1;int c[10] d[10]  
  2. for (int i=0;i<=2;i++,b[edx]=0)  
  3. {  
  4.     esi=eax;  
  5.     for(esi=eax;esi;esi=b[esi])  
  6.     {  
  7.         ecx=a[esi];  
  8.         取得特定位于ecx  
  9.         if(c[ecx]==0)  
  10.         {  
  11.             c[ecx]=esi;  
  12.         }  
  13.         else  
  14.         {  
  15.             b[ d[ecx] ]=esi;  
  16.         }  
  17.         d[ecx]=esi;  
  18.     }  
  19.     for(x=c[ecx=0];!x;ecx++)  
  20.         ;  
  21.     eax=c[ecx];edx=d[ecx];  
  22.     ecx++;  
  23.     for(;ecx<10;ecx++)  
  24.     {  
  25.         if(c[ecx])  
  26.         {  
  27.             b[edx]=c[ecx];  
  28.             edx=d[ecx];  
  29.         }  
  30.     }  
  31. }  



逆向之循环数组队列 

由于最近看了点除法优化的东西,这里就特意逆一个用取模比较多的程序吧,权当熟悉
版本:Release
优化选项:O2
调试工具:OD
源码:
[cpp] view plaincopyprint?
  1. #include <stdio.h>   
  2. #include <stdlib.h>   
  3.   
  4. #define FALSE 0   
  5. #define TRUE  1   
  6. #define MAX_SIZE 6   
  7. int capacity=MAX_SIZE;  
  8. enum {EXIT,ADD,DEL,SHOW};  
  9. typedef struct  
  10. {  
  11.     int element;  
  12. }queue;  
  13. queue q[MAX_SIZE];  
  14. int front=-1,rear=-1;   
  15.   
  16. int isempty()  
  17. {  
  18.     return rear%capacity==(front+capacity)%capacity;  
  19. }  
  20.   
  21. int isfull()  
  22. {  
  23.     return (rear+1)%capacity==(front+capacity)%capacity;  
  24. }  
  25.   
  26. int addq(int element)  
  27. {  
  28.     if(isfull()==TRUE)  
  29.     {  
  30.         fprintf(stderr,"queue is full,auto redouble...\n");  
  31.         return FALSE;  
  32.         //redouble();   
  33.     }  
  34.     rear=(rear+1)%capacity;  
  35.     q[rear].element=element;  
  36.     return TRUE;  
  37. }  
  38.   
  39. int deleteq()  
  40. {  
  41.     if(isempty())  
  42.     {  
  43.         fprintf(stderr,"empty");  
  44.         return FALSE;  
  45.     }  
  46.     front=(front+1)%capacity;  
  47.     return TRUE;  
  48. }  
  49.   
  50. void show()  
  51. {  
  52.     int i;  
  53.     if(isempty()==TRUE)  
  54.     {  
  55.         printf("empty\n");  
  56.         return;  
  57.     }  
  58.     for(i=front+1;i!=(rear+1)%capacity;i=(i+1)%capacity)  
  59.         printf("%d\t",q[i].element);  
  60.     putchar('\n');  
  61. }  
  62.   
  63. int main()  
  64. {  
  65.     int chose;  
  66.     int element;  
  67.     while(TRUE)  
  68.     {  
  69.         printf("ADD 1\nDEL 2\nSHOW 3\nEXIT 0\n");  
  70.         printf("please input chose: ");  
  71.         scanf("%d",&chose);  
  72.         fflush(stdin);  
  73.         switch(chose)  
  74.         {  
  75.             case ADD:  
  76.                 printf("please input add element :");  
  77.                 scanf("%d",&element);  
  78.                 fflush(stdin);  
  79.                 if(addq(element)==TRUE)  
  80.                     printf("add success\n");  
  81.                 else  
  82.                     printf("add failed...\n");  
  83.                 break;  
  84.             case DEL:  
  85.                 if(deleteq()==TRUE)  
  86.                     printf("del success\n");  
  87.                 else  
  88.                     printf("del failed\n");  
  89.                 break;  
  90.             case SHOW:  
  91.                 show();  
  92.                 break;  
  93.             case EXIT:  
  94.                 return 0;  
  95.             default:  
  96.                 printf("input error\n");  
  97.                 break;  
  98.         }  
  99.     }  
  100.     system("pause");  
  101.     return 0;  
  102. }  
  103.   
  104. 主函数就把switch case主要跳转代码贴上来,OD自动加上的注释已经很多了就不说  
  105. 00B91130  |> /68 3821B900   /push    00B92138                        ;  ASCII "ADD 1",LF,"DEL 2",LF,"SHOW 3",LF,"EXIT 0",LF  
  106. ...................................  
  107. ...................................  
  108. 00B9115C  |. |83F8 03       |cmp     eax, 3                          ;  Switch (cases 0..3)  
  109. 00B9115F  |. |0F87 BB000000 |ja      00B91220  
  110. 00B91165  |. |FF2485 3C12B9>|jmp     dword ptr [eax*4+B9123C]  
  111.   
  112. 00B9116C  |> |68 7021B900   |push    00B92170                        ;  ASCII "please input add element :"; Case 1 of switch 00B9115C  
  113. ..............................  
  114. ..............................  
  115. 00B911EE  |> |E8 0DFEFFFF   |call    deleteq                         ;  Case 2 of switch 00B9115C  
  116. ............................  
  117. ..........................  
  118. 00B91216  |> |E8 55FEFFFF   |call    show                            ;  Case 3 of switch 00B9115C  
  119. ............................  
  120. ............................  
  121.   
  122. 00B9122A  |.^\E9 01FFFFFF   \jmp     00B91130  
  123.   
  124. 00B9122F   ;这里就退出流程了  
  125. 用于case跳转的分支表  
  126. 00B9123C   . \2F12B900      dd      test.00B9122F                    ;  分支表 被用于 00B91165  
  127. 00B91240   .  6C11B900      dd      test.00B9116C  
  128. 00B91244   .  EE11B900      dd      test.00B911EE  
  129. 00B91248   .  1612B900      dd      test.00B91216  
  130.   
  131. addq函数代码  
  132. 00B91184  |.  A1 2030B900   |mov     eax, dword ptr [rear]               ;  eax=rear  
  133. 00B91189  |.  40            |inc     eax                                 ;  rear++  
  134. 00B9118A  |.  99            |cdq                                         ;  将rear扩展为64位(edx:eax)  
  135. 00B9118B  |.  B9 06000000   |mov     ecx, 6  
  136. 00B91190  |.  F7F9          |idiv    ecx                                 ;  rear/6  
  137. 00B91192  |.  A1 1C30B900   |mov     eax, dword ptr [front]              ;  eax=front  
  138. 00B91197  |.  83C0 06       |add     eax, 6                              ;  eax+=6  
  139. 00B9119A  |.  BD 06000000   |mov     ebp, 6  
  140. 00B9119F  |.  83C4 10       |add     esp, 10  
  141. 00B911A2  |.  8BCA          |mov     ecx, edx                            ;  将前面获得的余数存到ecx  
  142. 00B911A4  |.  99            |cdq  
  143. 00B911A5  |.  F7FD          |idiv    ebp                                 ;  eax/6  
  144. 00B911A7  |.  3BCA          |cmp     ecx, edx                            ;  if(ecx!=edx)  将2次获得的余数相比较  
  145. 00B911A9  |.  75 23         |jnz     short 00B911CE  
  146. 00B911AB  |.  68 0421B900   |push    00B92104                            ;  ASCII "queue is full,auto redouble...",LF  
  147. 00B911B0  |.  FFD7          |call    edi  
  148. 00B911B2  |.  83C0 40       |add     eax, 40                             ; |  
  149. 00B911B5  |.  50            |push    eax                                 ; |stream  
  150. 00B911B6  |.  FF15 A020B900 |call    dword ptr [<&MSVCR90.fprintf>]      ; \fprintf  
  151. 00B911BC  |.  83C4 08       |add     esp, 8  
  152. 00B911BF  |.  68 9C21B900   |push    00B9219C                            ;  ASCII "add failed...",LF  
  153. 00B911C4  |.  FFD6          |call    esi  
  154. 00B911C6  |.  83C4 04       |add     esp, 4  
  155. 00B911C9  |.^ E9 62FFFFFF   |jmp     00B91130  
  156. 00B911CE  |>  8B5424 14     |mov     edx, dword ptr [esp+14]             ;  esp+14处存储的是scanf输入的数  
  157. 00B911D2  |.  68 8C21B900   |push    00B9218C                            ;  ASCII "add success",LF  
  158. 00B911D7  |.  890D 2030B900 |mov     dword ptr [rear], ecx               ;  rear = ecx  
  159. 00B911DD  |.  89148D 7C33B9>|mov     dword ptr [ecx*4+q], edx            ;  q[rear]=[esp+14],即真正的入队操作  
  160. 00B911E4  |.  FFD6          |call    esi  
  161.   
  162.   
  163. 下面是deleteq函数  
  164. 00B91000 >/$  8B0D 2030B900 mov     ecx, dword ptr [rear]                ;  ecx=rear  
  165. 00B91006  |.  B8 ABAAAA2A   mov     eax, 2AAAAAAB                        ;  下面几个指令是取模优化,这个16进制数用小数方式来计算大概是0.16左右的值,其实源码也就是1/6了  
  166. 00B9100B  |.  F7E9          imul    ecx  
  167. 00B9100D  |.  8BC2          mov     eax, edx  
  168. 00B9100F  |.  C1E8 1F       shr     eax, 1F  
  169. 00B91012  |.  03C2          add     eax, edx                             ;  这里eax即为rear/6的结果  
  170. 00B91014  |.  8D0440        lea     eax, dword ptr [eax+eax*2]  
  171. 00B91017  |.  03C0          add     eax, eax  
  172. 00B91019  |.  56            push    esi  
  173. 00B9101A  |.  8B35 1C30B900 mov     esi, dword ptr [front]  
  174. 00B91020  |.  2BC8          sub     ecx, eax                             ;  这里ecx才是真正取模的结果  
  175. 00B91022  |.  8D46 06       lea     eax, dword ptr [esi+6]               ;  先加6再取模  
  176. 00B91025  |.  57            push    edi  
  177. 00B91026  |.  99            cdq  
  178. 00B91027  |.  BF 06000000   mov     edi, 6  
  179. 00B9102C  |.  F7FF          idiv    edi  
  180. 00B9102E  |.  3BCA          cmp     ecx, edx                             ;  if ((front+6)%6)!=(rear%6)  
  181. 00B91030  |.  75 1D         jnz     short 00B9104F  
  182. 00B91032  |.  68 2421B900   push    00B92124                             ;  ASCII "empty"  
  183. 00B91037  |.  FF15 AC20B900 call    dword ptr [<&MSVCR90.__iob_func>]    ;  MSVCR90.__p__iob  
  184. 00B9103D  |.  83C0 40       add     eax, 40                              ; |  
  185. 00B91040  |.  50            push    eax                                  ; |stream  
  186. 00B91041  |.  FF15 A020B900 call    dword ptr [<&MSVCR90.fprintf>]       ; \fprintf  
  187. 00B91047  |.  83C4 08       add     esp, 8  
  188. 00B9104A  |.  5F            pop     edi  
  189. 00B9104B  |.  33C0          xor     eax, eax  
  190. 00B9104D  |.  5E            pop     esi  
  191. 00B9104E  |.  C3            retn  
  192. 00B9104F  |>  8D46 01       lea     eax, dword ptr [esi+1]               ;  front=(front+1)%6  
  193. 00B91052  |.  99            cdq  
  194. 00B91053  |.  8BCF          mov     ecx, edi  
  195. 00B91055  |.  F7F9          idiv    ecx  
  196. 00B91057  |.  5F            pop     edi  
  197. 00B91058  |.  B8 01000000   mov     eax, 1  
  198. 00B9105D  |.  5E            pop     esi  
  199. 00B9105E  |.  8915 1C30B900 mov     dword ptr [front], edx  
  200. 00B91064  \.  C3            retn  
  201.   
  202.   
  203. 最后一个show函数有兴趣自己看看吧,就加点提示不多注释了  
  204. 00B91070 >/$  8B0D 2030B900 mov     ecx, dword ptr [rear]                ;  rear%6!=(front+6)%6  
  205. 00B91076  |.  B8 ABAAAA2A   mov     eax, 2AAAAAAB  
  206. 00B9107B  |.  F7E9          imul    ecx  
  207. 00B9107D  |.  8BC2          mov     eax, edx  
  208. 00B9107F  |.  C1E8 1F       shr     eax, 1F  
  209. 00B91082  |.  03C2          add     eax, edx  
  210. 00B91084  |.  53            push    ebx  
  211. 00B91085  |.  8D0440        lea     eax, dword ptr [eax+eax*2]  
  212. 00B91088  |.  56            push    esi  
  213. 00B91089  |.  8B35 1C30B900 mov     esi, dword ptr [front]  
  214. 00B9108F  |.  03C0          add     eax, eax  
  215. 00B91091  |.  57            push    edi  
  216. 00B91092  |.  8BF9          mov     edi, ecx  
  217. 00B91094  |.  2BF8          sub     edi, eax  
  218. 00B91096  |.  8D46 06       lea     eax, dword ptr [esi+6]  
  219. 00B91099  |.  99            cdq  
  220. 00B9109A  |.  BB 06000000   mov     ebx, 6  
  221. 00B9109F  |.  F7FB          idiv    ebx  
  222. 00B910A1  |.  3BFA          cmp     edi, edx  
  223. 00B910A3  |.  75 12         jnz     short 00B910B7  
  224. 00B910A5  |.  68 2C21B900   push    00B9212C                             ; /format = "empty",LF,""  
  225. 00B910AA  |.  FF15 A420B900 call    dword ptr [<&MSVCR90.printf>]        ; \printf  
  226. 00B910B0  |.  83C4 04       add     esp, 4  
  227. 00B910B3  |.  5F            pop     edi  
  228. 00B910B4  |.  5E            pop     esi  
  229. 00B910B5  |.  5B            pop     ebx  
  230. 00B910B6  |.  C3            retn  
  231. 00B910B7  |>  8D41 01       lea     eax, dword ptr [ecx+1]               ;  front+1!=rear+1%6  
  232. 00B910BA  |.  99            cdq  
  233. 00B910BB  |.  8BCB          mov     ecx, ebx  
  234. 00B910BD  |.  F7F9          idiv    ecx  
  235. 00B910BF  |.  46            inc     esi  
  236. 00B910C0  |.  3BF2          cmp     esi, edx  
  237. 00B910C2  |.  74 35         je      short 00B910F9  
  238. 00B910C4  |.  8B3D A420B900 mov     edi, dword ptr [<&MSVCR90.printf>]   ;  MSVCR90.printf  
  239. 00B910CA  |.  8D9B 00000000 lea     ebx, dword ptr [ebx]  
  240. 00B910D0  |>  8B14B5 7C33B9>/mov     edx, dword ptr [esi*4+q]  
  241. 00B910D7  |.  52            |push    edx  
  242. 00B910D8  |.  68 3421B900   |push    00B92134                            ;  ASCII "%d",TAB  
  243. 00B910DD  |.  FFD7          |call    edi  
  244. 00B910DF  |.  8D46 01       |lea     eax, dword ptr [esi+1]              ;  front=(front+1)%6  
  245. 00B910E2  |.  99            |cdq  
  246. 00B910E3  |.  8BCB          |mov     ecx, ebx  
  247. 00B910E5  |.  F7F9          |idiv    ecx  
  248. 00B910E7  |.  A1 2030B900   |mov     eax, dword ptr [rear]  
  249. 00B910EC  |.  40            |inc     eax  
  250. 00B910ED  |.  83C4 08       |add     esp, 8  
  251. 00B910F0  |.  8BF2          |mov     esi, edx  
  252. 00B910F2  |.  99            |cdq  
  253. 00B910F3  |.  F7F9          |idiv    ecx  
  254. 00B910F5  |.  3BF2          |cmp     esi, edx  
  255. 00B910F7  |.^ 75 D7         \jnz     short 00B910D0  
  256. 00B910F9  |>  6A 0A         push    0A                                   ; /c = 0A  (Line Feed)  
  257. 00B910FB  |.  FF15 9C20B900 call    dword ptr [<&MSVCR90.putchar>]       ; \putchar  
  258. 00B91101  |.  83C4 04       add     esp, 4  
  259. 00B91104  |.  5F            pop     edi  
  260. 00B91105  |.  5E            pop     esi  
  261. 00B91106  |.  5B            pop     ebx  
  262. 00B91107  \.  C3            retn  

原创粉丝点击