• [asm] 小菜汇编基础和学习技巧小结(一)


       以下小结纯属小菜自学过程产生的dump,大神请飘过!

        汇编是一门庞大复杂的学问,在计算机的世界里差不多无所不入。很多编程领域都会或多或少跟汇编打交道。本人不是科班出身的程序员,所以很多基础都为零,学历也很低。因此学习汇编的难度可想而知。不过还是凭自己的耐力,掌握了少许的知识。下面做个小小的总结,分享给和我一样想入门汇编的朋友们。

       1.参数直接传值和传入数值变量的区别

    void SetX(int x)
    {
        x = 6;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        SetX(7);//1.直接传数值
    
        int x = 7;
        SetX(x);//2.传一个有初始值的变量
        return 0;
    }

    这两种情况运行的结果没有任何区别,但是汇编代码却有些细微的区别:

    第一种情况:

     push        7  
     call        SetX (01011E5h)  //1.直接传值
     add         esp,4  //栈指针向下移动

    第二种情况多了一个将及时数缓存于内存x的步骤:

     mov         dword ptr [x],7  //首先将及时数7传入双字型内存地址为x的内存中
     mov         eax,dword ptr [x]  //然后再将x里的值传到eax寄存器里
     push        eax   //开始压入参数值
     call        SetX (01011E5h)  
     add         esp,4  //栈指针向下移动,清除变量
     xor         eax,eax  //清空eax的值

    2.有返回值与没返回值的区别
    在c++或其他高级语言,我们可以一眼看出返回值和返回类型。但是汇编里貌似有些乱。在上面的例子里,Call完SetX之后,后面就紧跟着开始清除变量值。这个还不能说明有没有返回值。再来看一个例子就能明显分辨有没有返回值了。

    int SetX(int x)
    {
        x = 6;
        return x;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        SetX(7);//1.有返回值,但是没有引用
        int x=SetX(7);//2.有返回值,并且引用了
        return 0;
    }
    View Code

    这个例子里,第一个函数调用没有赋值的动作,且看对应的汇编代码:

     push        7  
     call        SetX (012811EAh)  
     add         esp,4  

    这个情况看起来就如果本身就不带返回值的情况。看起来没法这样分辨了,但是其实如果是这样调用,不就个没带返回值效果是一样的了。判别有没有返回值已经没有意义了。

     push        7  
     call        SetX (012811EAh)  
     add         esp,4  
     mov         dword ptr [x],eax  
     xor         eax,eax  

    上面的第二种情况,则明显多了一个mov指令。在调用完函数之后,立马来个mov,显然是返回了一个值存于eax,需要立即保存在地址x的内存里。很明显是带返回值的。

    3.参数传递中值传递和引用传递的区别

    void SetX(int x)
    {
        x++;
    }
    void SetY(int &y)
    {
        y++;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        int x = 0;
        int y = 0;
        SetX(x);//1.值传递,x的值不会变
        SetY(y);//2.引用传递,y的值会产生变化
        return 0;
    }

    在汇编码里,更容易看出两个函数的不同
    对于第一个函数:

     mov         eax,dword ptr [x]  
     push        eax  
     call        SetX (01611F4h)  
     add         esp,4  

    明显是将地址为x的内存里的值传入eax,再经由eax传给函数。而对于第二个函数,先是用lea取一块有效的内存区域用于存储计算过程中生成的结果。然后将这个刚刚建立的内存区域的地址传给eax,以便可以直接操作y区域的内存。

     lea         eax,[y]  
     push        eax  
     call        SetY (01611EFh)  
     add         esp,4  
     xor         eax,eax  


    这几个小细节在汇编,甚至反汇编的时候非常有使用价值。

  • 相关阅读:
    vue关于样式的绑定
    vue插口
    vue组件 父子 通讯
    vue实现翻页功能加高阶函数加购物车
    MySQL 索引面试总结
    phpstorm配置git并解决Terminal 中文乱码(Unicode 编码)的方法
    php 下载图片并打包成Zip格式压缩包
    MySQL5.6升级到5.7详细教程
    windows下安装vue教程
    一致性hash算法详解
  • 原文地址:https://www.cnblogs.com/uu102/p/3958966.html
Copyright © 2020-2023  润新知