20110722 学习简单汇编指令 for if等

生成一段for代码 反编译看之
     6: int myfunction(int a,int b)
     7: {
01381380  push        ebp    /
01381381  mov         ebp,esp 
01381383  sub         esp,0D8h 
01381389  push        ebx  
0138138A  push        esi  
0138138B  push        edi  
0138138C  lea         edi,[ebp-0D8h] 
01381392  mov         ecx,36h 
01381397  mov         eax,0CCCCCCCCh 
0138139C  rep stos    dword ptr es:[edi]      到这里位置是标准的函数入口把参数从右到做分别压入堆栈 没什么好学习的 重点看下面
     8:   int c=a+b;
0138139E  mov         eax,dword ptr [a]  //首先把a变了赋值给eax 
013813A1  add         eax,dword ptr [b]  //同上不过换成了B变量
013813A4  mov         dword ptr [c],eax ///三句指令获得的就是int c=a+b;
     9:   int i;
    10:     for(i=0;i<50;i++)
013813A7  mov         dword ptr [i],0  //初始化I=0
013813AE  jmp         myfunction+39h (13813B9h) 然后直接跳到循环的开始处 
013813B0  mov         eax,dword ptr [i] ///这是从下面的无条件跳转 到这里进行循环的++操作
013813B3  add         eax,1 //上面把I赋值到eax这里把eax加1
013813B6  mov         dword ptr [i],eax //然后把eax再赋值给I 下面接着进行对比
013813B9  cmp         dword ptr [i],32h  //i与50对比 这里的50=32(16进制)转换为8进制
013813BD  jge         myfunction+4Ah (13813CAh)  //jge跳转条件满足则跳转 这里的条件就是只i不小于50
    11:     {
    12:       c= c+i;
013813BF  mov         eax,dword ptr [c]   //如果上述跳转实现不了的话就执行这一句初始化C的值
013813C2  add         eax,dword ptr [i]  // eax+i就等于C的值  
013813C5  mov         dword ptr [c],eax   //然后把eax赋值给C就获得了C=C+I 之所以这么麻烦因为是debug编译模式下 具体为啥不得而知
    13:     }
013813C8  jmp         myfunction+30h (13813B0h) //跳转回去进行循环
    14:     return c;
013813CA  mov         eax,dword ptr [c]  //在汇编语句中 所有的变量值都是保存在eax中
    15: 
  16: }
  Push 操作会吧栈顶-4 就是esp-4  而pop相应的+4
  通过以上代码我们得出结论 for的asm结构就是
  mov<循环变量的值><初始值>  也就是上面给I赋值的地方
  Jmp B  也就是赋值后进入第一次循环对比的 地方
  
  A:(改动循环变量值)
  
  B:cmp(循环变量)(最大值)
     Jge 跳出循环 大于等于则跳
    (主循环体).....
  Jmp A  如果jge不能形成这跳到A处
  然后学习Do循环
   9:   do{
    10:      c=c+i;
001E341E  mov         eax,dword ptr [c]  
001E3421  add         eax,dword ptr [i]       这三句代码的意思不用说已经很明白了
001E3424  mov         dword ptr [c],eax     
    11:   }while(c<100);
001E3427  cmp         dword ptr [c],64h 循环对比的地方64h这种16进制已经讲了转换为8进制
001E342B  jl          myfunction+1Eh (1E341Eh) //跳回去 jl小于则跳
    12: return c;
001E342D  mov         eax,dword ptr [c] //返回C的值
      13: }  因为DO没有去修改变量值所以代码灰常简单与河蟹
  
  
  接下来是while循环 此循环体在C++编写中经常用到 
  反汇编代码
     9: while(c<100)
013E341E  cmp         dword ptr [c],64h  直接对比
013E3422  jge         myfunction+2Fh (13E342Fh)  大于等于则跳
    10: {
    11:   c = c+i;
013E3424  mov         eax,dword ptr [c] 
013E3427  add         eax,dword ptr [i] 
013E342A  mov         dword ptr [c],eax  到这里就是把运算结果赋值给C
    12: }
013E342D  jmp         myfunction+1Eh (13E341Eh) 跳入循环体
    13: 
    14: return c;
013E342F  mov         eax,dword ptr [c] 返回最后值

   获得结构如下
  A Cmp(循环变量值)(最大值)
  Jge B 大于等于则跳
  ......
  Jmp A
  B 循环外
  
  - --------------------------循环体大致就是cmp jge jg jmp等 下面是if等语法
  
    10: if(c>0&&c<10)
01012E3E  cmp         dword ptr [c],0   //我们可以看到 首先c>0对比
01012E42  jle         myfunction+43h (1012E63h) //如果小于的话就跳走
01012E44  cmp         dword ptr [c],0Ah //如果上一个条件满足 则判断c是否小于10
01012E48  jge         myfunction+43h (1012E63h) 大于等于则跳
    11: {
    12:   printf("c>0");
01012E4A  mov         esi,esp 
01012E4C  push        offset string "c>0" (101573Ch) 
01012E51  call        dword pt         _printf (10182B4h)]               这里是输出部分先不管
01012E57  add         esp,4  
01012E5A  cmp         esi,esp 
01012E5C  call        @ILT+455(__RTC_CheckEsp) (10111CCh) 
01012E61  jmp         myfunction+7Fh (1012E9Fh) 这里的话直接调走了 因为if条件已经全部满足则不需要进行下面的判断
    13: 
    14: }
    15: else if(c>10&&c<100)
01012E63  cmp         dword ptr [c],0Ah 
01012E67  jle         myfunction+68h (1012E88h) 
01012E69  cmp         dword ptr [c],64h 
01012E6D  jge         myfunction+68h (1012E88h) 
    16: {
    17:   printf("c>10&&c<100");
01012E6F  mov         esi,esp 
01012E71  push        offset string "c>10&&c<100" (10157A0h) 
01012E76  call        dword ptr [__imp__printf (10182B4h)] 
01012E7C  add         esp,4 
01012E7F  cmp         esi,esp 
01012E81  call        @ILT+455(__RTC_CheckEsp) (10111CCh) 
    18: }
    19: else
01012E86  jmp         myfunction+7Fh (1012E9Fh) 
    20: {
    21:   printf("c>10&&c<100");
01012E88  mov         esi,esp 
01012E8A  push        offset string "c>10&&c<100" (10157A0h) 
01012E8F  call        dword ptr [__imp__printf (10182B4h)] 
01012E95  add         esp,4 
01012E98  cmp         esi,esp 
01012E9A  call        @ILT+455(__RTC_CheckEsp) (10111CCh) 
    22: }
    23: 
    24: return c;
01012E9F  mov         eax,dword ptr [c] 
      25: 
  }
  大体上我们获得if 判断就是 cmp 与jle 条件不满足直接调走 如满足则到下一个条件分支
  Switch-case分支判断
001C2E3E  mov         eax,dword ptr [c] 
001C2E41  mov         dword ptr [ebp-0C4h],eax                                    首先把C移动到ebp-0c4h的地方
001C2E47  cmp         dword ptr [ebp-0C4h],0 与0进行对
001C2E4E  je          myfunction+3Bh (1C2E5Bh) 大于则跳
001C2E50  cmp         dword ptr [ebp-0C4h],1 与1进行对比
001C2E57  je          myfunction+52h (1C2E72h) 大于则跳
001C2E59  jmp         myfunction+6Bh (1C2E8Bh) 
    11: {
    12: case 0:
    13:   printf("C>0");
001C2E5B  mov         esi,esp 
001C2E5D  push        offset string "c>0" (1C573Ch) 
001C2E62  call        dword ptr [__imp__printf (1C82B4h)] 
001C2E68  add         esp,4 
001C2E6B  cmp         esi,esp 
001C2E6D  call        @ILT+455(__RTC_CheckEsp) (1C11CCh) 
    14: 
    15: case 1:
    16:   {
    17:     printf("C>10&&c<100");
001C2E72  mov         esi,esp 
001C2E74  push        offset string "C>10&&c<100" (1C57A0h) 
001C2E79  call        dword ptr [__imp__printf (1C82B4h)] 
001C2E7F  add         esp,4 
001C2E82  cmp         esi,esp 
001C2E84  call        @ILT+455(__RTC_CheckEsp) (1C11CCh) 
    18:     break;
001C2E89  jmp         myfunction+82h (1C2EA2h) 
    19:   }
    20: default:
    21:   printf("C>10&&c<100");
001C2E8B  mov         esi,esp 
001C2E8D  push        offset string "C>10&&c<100" (1C57A0h) 
001C2E92  call        dword ptr [__imp__printf (1C82B4h)] 
001C2E98  add         esp,4 
001C2E9B  cmp         esi,esp 
001C2E9D  call        @ILT+455(__RTC_CheckEsp) (1C11CCh) 
    22: }
      23: return c;
  
  以上为判断与循环语句的asm分析