一篇有關舞伴問題的主函數的彙編的分析-2019.10.27

序言:
一次有關數據結構中舞伴問題的彙編分析,由於時間問題本文僅僅是對主函數的分析。

主函數的截圖和代碼

在這裏插入圖片描述

下面是主函數的代碼:

int main()
{
 int m,n,k;
 system("color f0");//控制檯顏色
 printf("請輸入三個數字(以空格隔開)第一個代表男生人數,第二個代表女生人數,第三個代表共需要幾對舞伴,請輸入:\n");
 scanf("%d%d%d",&m,&n,&k);
 //建立兩個隊列 存放男女編號 
 LinkQueue Q1;
 InitQueue(&Q1);
 for(int i=1;i<=m;i++)
 {
  EnQueue(&Q1,i);
 }
 LinkQueue Q2;
 InitQueue(&Q2);
 for(int p=1;p<=n;p++)
 {
  EnQueue(&Q2,i);
 }
 //用兩個指針 遍歷兩個隊列 打印編號 
 QDataNode *p1,*p2;
 p1=Q1->front->next;
 p2=Q2->front->next; 
 for(int o=0;o<k;o++)//循環遍歷k次 
 {
  printf("%d %d\n",p1->x,p2->x);
  p1=p1->next;
  p2=p2->next;
 }system("pause");
 return 0;

下面是彙編代碼的分析

彙編的截圖:

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述下面是彙編的代碼:

38:   int main()
39:   {
00401170   push        ebp
00401171   mov         ebp,esp
00401173   sub         esp,68h
00401176   push        ebx
00401177   push        esi
00401178   push        edi
00401179   lea         edi,[ebp-68h]
0040117C   mov         ecx,1Ah
00401181   mov         eax,0CCCCCCCCh
00401186   rep stos    dword ptr [edi]
40:       int m,n,k;
41:       system("color f0");
00401188   push        offset string "color f0" (004350b0)
0040118D   call        system (0040a470)
00401192   add         esp,4
42:       printf("請輸入三個數字(以空格隔開)第一個代表男生人數,第二個代表女生人數,第三個代表共需要幾對舞伴,請輸入:\n");
00401195   push        offset string "\xc7\xeb\xca\xe4\xc8\xeb\xc8\xfd\xb8\xf6\xca\xfd\xd7\xd6\xa3\xa8\xd2\xd4\
0040119A   call        printf (0040a3f0)
0040119F   add         esp,4
43:       scanf("%d%d%d",&m,&n,&k);
004011A2   lea         eax,[ebp-0Ch]
004011A5   push        eax
004011A6   lea         ecx,[ebp-8]
004011A9   push        ecx
004011AA   lea         edx,[ebp-4]
004011AD   push        edx
004011AE   push        offset string "%d%d%d" (0043502c)
004011B3   call        scanf (0040a390)
004011B8   add         esp,10h
44:       //建立兩個隊列 存放男女編號
45:       LinkQueue Q1;
46:       InitQueue(&Q1);
004011BB   lea         eax,[ebp-10h]
004011BE   push        eax
004011BF   call        @ILT+0(InitQueue) (00401005)
004011C4   add         esp,4
47:       for(int i=1;i<=m;i++)
004011C7   mov         dword ptr [ebp-14h],1
004011CE   jmp         main+69h (004011d9)
004011D0   mov         ecx,dword ptr [ebp-14h]
004011D3   add         ecx,1
004011D6   mov         dword ptr [ebp-14h],ecx
004011D9   mov         edx,dword ptr [ebp-14h]
004011DC   cmp         edx,dword ptr [ebp-4]
004011DF   jg          main+83h (004011f3)
48:       {
49:           EnQueue(&Q1,i);
004011E1   mov         eax,dword ptr [ebp-14h]
004011E4   push        eax
004011E5   lea         ecx,[ebp-10h]
004011E8   push        ecx
004011E9   call        @ILT+15(EnQueue) (00401014)
004011EE   add         esp,8
50:       }
004011F1   jmp         main+60h (004011d0)
51:       LinkQueue Q2;
52:       InitQueue(&Q2);
004011F3   lea         edx,[ebp-18h]
004011F6   push        edx
004011F7   call        @ILT+0(InitQueue) (00401005)
004011FC   add         esp,4
53:       for(int p=1;p<=n;p++)
004011FF   mov         dword ptr [ebp-1Ch],1
00401206   jmp         main+0A1h (00401211)
00401208   mov         eax,dword ptr [ebp-1Ch]
0040120B   add         eax,1
0040120E   mov         dword ptr [ebp-1Ch],eax
00401211   mov         ecx,dword ptr [ebp-1Ch]
00401214   cmp         ecx,dword ptr [ebp-8]
00401217   jg          main+0BBh (0040122b)
54:       {
55:           EnQueue(&Q2,i);
00401219   mov         edx,dword ptr [ebp-14h]
0040121C   push        edx
0040121D   lea         eax,[ebp-18h]
00401220   push        eax
00401221   call        @ILT+15(EnQueue) (00401014)
00401226   add         esp,8
56:       }
00401229   jmp         main+98h (00401208)
57:       //用兩個指針 遍歷兩個隊列 打印編號
58:       QDataNode *p1,*p2;
59:       p1=Q1->front->next;
0040122B   mov         ecx,dword ptr [ebp-10h]
0040122E   mov         edx,dword ptr [ecx]
00401230   mov         eax,dword ptr [edx+4]
00401233   mov         dword ptr [ebp-20h],eax
60:       p2=Q2->front->next;
00401236   mov         ecx,dword ptr [ebp-18h]
00401239   mov         edx,dword ptr [ecx]
0040123B   mov         eax,dword ptr [edx+4]
0040123E   mov         dword ptr [ebp-24h],eax
61:       for(int o=0;o<k;o++)//循環遍歷k次
00401241   mov         dword ptr [ebp-28h],0
00401248   jmp         main+0E3h (00401253)
0040124A   mov         ecx,dword ptr [ebp-28h]
0040124D   add         ecx,1
00401250   mov         dword ptr [ebp-28h],ecx
00401253   mov         edx,dword ptr [ebp-28h]
00401256   cmp         edx,dword ptr [ebp-0Ch]
00401259   jge         main+118h (00401288)
62:       {
63:           printf("%d %d\n",p1->x,p2->x);
0040125B   mov         eax,dword ptr [ebp-24h]
0040125E   mov         ecx,dword ptr [eax]
00401260   push        ecx
00401261   mov         edx,dword ptr [ebp-20h]
00401264   mov         eax,dword ptr [edx]
00401266   push        eax
00401267   push        offset string "%d %d\n" (00435024)
0040126C   call        printf (0040a3f0)
00401271   add         esp,0Ch
64:           p1=p1->next;
00401274   mov         ecx,dword ptr [ebp-20h]
00401277   mov         edx,dword ptr [ecx+4]
0040127A   mov         dword ptr [ebp-20h],edx
65:           p2=p2->next;
0040127D   mov         eax,dword ptr [ebp-24h]
00401280   mov         ecx,dword ptr [eax+4]
00401283   mov         dword ptr [ebp-24h],ecx
66:       }system("pause");
00401286   jmp         main+0DAh (0040124a)
00401288   push        offset string "pause" (0043501c)
0040128D   call        system (0040a470)
00401292   add         esp,4
67:       return 0;
00401295   xor         eax,eax
68:   }
00401297   pop         edi
00401298   pop         esi
00401299   pop         ebx
0040129A   add         esp,68h
0040129D   cmp         ebp,esp
0040129F   call        __chkesp (0040a350)
004012A4   mov         esp,ebp
004012A6   pop         ebp
004012A7   ret

00401170 push ebp
00401171 mov ebp,esp
00401173 sub esp,68h
00401176 push ebx
00401177 push esi
00401178 push edi
00401179 lea edi,[ebp-68h]
0040117C mov ecx,1Ah
00401181 mov eax,0CCCCCCCCh
00401186 rep stos dword ptr [edi]

這些代碼實在進行一些函數初始化的工作,進行寄存器的壓入和保存的,爲接下來要進行的工作做準備。

00401188 push offset string “color f0” (004350b0)
0040118D call system (0040a470)
00401192 add esp,4

這裏是調用了系統中的一些指令使得控制檯變爲白色的

004011A2 lea eax,[ebp-0Ch]
004011A5 push eax
004011A6 lea ecx,[ebp-8]
004011A9 push ecx
004011AA lea edx,[ebp-4]
004011AD push edx
004011AE push offset string “%d%d%d” (0043502c)
004011B3 call scanf (0040a390)
004011B8 add esp,10h

讀取用戶輸入的三個數值,並且這三個數值的地址是連在一起,並且這裏還要注意,棧的是按照“先進後出”的原則的,所以最下面的[ebp-4]的地址中存放的是m

004011BB lea eax,[ebp-10h]
004011BE push eax
004011BF call @ILT+0(InitQueue) (00401005)
004011C4 add esp,4

再度提升棧的空間,然後把Q1放入,再調用初始化函數

004011FF mov dword ptr [ebp-1Ch],1
00401206 jmp main+0A1h (00401211)
00401208 mov eax,dword ptr [ebp-1Ch]
0040120B add eax,1
0040120E mov dword ptr [ebp-1Ch],eax
00401211 mov ecx,dword ptr [ebp-1Ch]
00401214 cmp ecx,dword ptr [ebp-8]
00401217 jg main+0BBh (0040122b)

這裏是for循環,把1放入[ebp-1Ch]即
然後強制跳轉到00401211這個地址
然後產生比較也就是判斷
然後決定向那個地方跳轉
下面是for循環中語句

00401219 mov edx,dword ptr [ebp-14h]
0040121C push edx
0040121D lea eax,[ebp-18h]
00401220 push eax
00401221 call @ILT+15(EnQueue) (00401014)
00401226 add esp,8

調用了一個函數EnQueue()上面的代碼也是和函數的初始化以及一些寄存器的壓棧

00401229 jmp main+98h (00401208)

強制跳轉到00401208

00401208 mov eax,dword ptr [ebp-1Ch]
0040120B add eax,1
0040120E mov dword ptr [ebp-1Ch],eax

到這裏for循環就算分析的差不多了
不過還有就是最爲重要的跳出去的代碼

00401217 jg main+0BBh (0040122b)

0040122B mov ecx,dword ptr [ebp-10h]
0040122E mov edx,dword ptr [ecx]
00401230 mov eax,dword ptr [edx+4]
00401233 mov dword ptr [ebp-20h],eax
00401236 mov ecx,dword ptr [ebp-18h]
00401239 mov edx,dword ptr [ecx]
0040123B mov eax,dword ptr [edx+4]
0040123E mov dword ptr [ebp-24h],eax

這裏是進行了p1和p2的初始化

00401241 mov dword ptr [ebp-28h],0
00401248 jmp main+0E3h (00401253)
0040124A mov ecx,dword ptr [ebp-28h]
0040124D add ecx,1
00401250 mov dword ptr [ebp-28h],ecx
00401253 mov edx,dword ptr [ebp-28h]
00401256 cmp edx,dword ptr [ebp-0Ch]
00401259 jge main+118h (00401288)

接着再進行一個循環
進行的是for(int o=0;o<k;o++)

0040125B mov eax,dword ptr [ebp-24h]
0040125E mov ecx,dword ptr [eax]
00401260 push ecx
00401261 mov edx,dword ptr [ebp-20h]
00401264 mov eax,dword ptr [edx]
00401266 push eax
00401267 push offset string “%d %d\n” (00435024)
0040126C call printf (0040a3f0)
00401271 add esp,0Ch

對printf()函數的調用

00401274 mov ecx,dword ptr [ebp-20h]
00401277 mov edx,dword ptr [ecx+4]
0040127A mov dword ptr [ebp-20h],edx
0040127D mov eax,dword ptr [ebp-24h]
00401280 mov ecx,dword ptr [eax+4]
00401283 mov dword ptr [ebp-24h],ecx

p1=p1->next;p2=p2->next;

00401286 jmp main+0DAh (0040124a)
00401288 push offset string “pause” (0043501c)
0040128D call system (0040a470)
00401292 add esp,4

這裏執行的是讓程序停止下來的
system(“pause”);(我爲了方便調試寫的…)

00401295 xor eax,eax
return 0;

00401297 pop edi
00401298 pop esi
00401299 pop ebx
0040129A add esp,68h
0040129D cmp ebp,esp
0040129F call __chkesp (0040a350)
004012A4 mov esp,ebp
004012A6 pop ebp
004012A7 ret

出棧恢復要來的寄存器和指針的值

今天就先分析一個比較簡單,慢慢來逐漸加深難度。加油

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章