首页
社区
课程
招聘
[旧帖] [原创]asm学习笔记之简单循环与判断 0.00雪花
发表于: 2011-7-22 15:48 3900

[旧帖] [原创]asm学习笔记之简单循环与判断 0.00雪花

2011-7-22 15:48
3900

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变量
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分析


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
2
vc++6.0编译器的结果吧,呵呵。顶楼主一个= =
2011-7-22 19:29
0
雪    币: 343
活跃值: (40)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
感谢楼主分享
2011-7-22 19:40
0
雪    币: 8
活跃值: (33)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
VS2008 debug模式
2011-7-22 19:52
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
5
嘿嘿
2011-7-23 19:20
0
雪    币: 105
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
强烈支持!继续加油!
2011-7-24 12:59
0
雪    币: 50
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
学习啦,继续努力
2011-7-25 14:34
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
来学习了--  - -
2011-7-25 14:48
0
游客
登录 | 注册 方可回帖
返回
//