一篇有关舞伴问题的主函数的汇编的分析-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

出栈恢复要来的寄存器和指针的值

今天就先分析一个比较简单,慢慢来逐渐加深难度。加油

在这里插入图片描述

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