• rep stos 指令(Intel汇编)


    今天读代码时,忽然跳出如下一条指令==>>
    汇编代码: rep stos dword ptr es:[edi]

    在网上查了相关资料显示:
    /************************************************************/
    lea     edi,[ebp-0C0h] 
    mov     ecx,30h 
    mov     eax,0CCCCCCCCh 
    rep stos dword ptr es:[edi]
    rep指令的目的是重复其上面的指令.ECX的值是重复的次数.
    STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址.


    如果设置了direction flag, 那么edi会在该指令执行后减小, 
    如果没有设置direction flag, 那么edi的值会增加.

     

    REP可以是任何字符传指令(CMPS, LODS, MOVS, SCAS, STOS)的前缀. 
    REP能够引发其后的字符串指令被重复, 只要ecx的值不为0, 重复就会继续. 
    每一次字符串指令执行后, ecx的值都会减小.

    stos((store into String),意思是把eax的内容拷贝到目的地址。
    用法:stos dst,dst是一个目的地址,例如:stos dword ptr es:[edi]。dword ptr前缀告诉stos,一次拷贝双字(4个字节)的数据到目的地址。为什么一次非要拷贝双字呢?这和eax寄存器有关,到底神马关系,慢慢道来。。
    执行stos之前必须往eax(32为寄存器)放入要拷贝的数据。上图中,eax的内容是cccccccc,不用说都明白int3中断。
    这段代码是初始化堆栈和分配局部变量用的,往分配好的局部变量空间放入int3中断的原因是:防止该空间里的东东被意外执行。


    /************************************************************/

    想了想,没怎么明白,于是直接写了个函数,来加深一下印象:
    /************************************************************/
    #include <stdio.h>
    int main()
    {
     int i;
     int result=0;

     _asm{
      mov edi,edi
      mov edi,edi
     }

     for (i=0;i<20;++i)
      result+=2;
     return result;
    }
    /************************************************************/
    其中,
     _asm{
      mov edi,edi
      mov edi,edi
     }
    是没有任何作用的,只是为了让我们在反汇编时好定位代码的位置。

     

    然后用OD打开,找到我们的代码处:
    /************************************************************/


    /************************************************************/

    LEA: 目标地址传送指令: 将一个近地址指针写入到指定的寄存器。
    区别MOV传送指令:MOV传送的是地址所指的内容,而LEA只是地址。

    另外,在二进制中,0xCC 对应的就是汇编的:int 3指令(中断).


    push ebp
    mov ebp,esp
    sub  esp,40h
    push ebx
    push esi
    push edi
    lea edi,[ebp-40h]
    mov ecx,10h
    mov eax,0CCCCCCCCh
    rep stos dword ptr [edi]
    
    开始:
    // ESP = 0013FF30 EBP = 0013FF80
    
    push        ebp               
    
    // ESP = 0013FF2C EBP = 0013FF80
    
    mov         ebp,esp           
    
    // ESP = 0013FF2C EBP = 0013FF2C     <==== 注意 ESP
    
    sub         esp,40h           
    
    // ESP = 0013FEEC EBP = 0013FF2C
    
    push        ebx               
    
    // ESP = 0013FEE8 EBP = 0013FF2C
    
    push        esi               
    
    // ESP = 0013FEE4 EBP = 0013FF2C
    
    push        edi               
    
    // ESP = 0013FEE0 EBP = 0013FF2C
    
    lea         edi,[ebp-40h]     
    
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEEC
    
    mov         ecx,10h           
    
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEEC ECX = 00000010
    
    mov         eax,0CCCCCCCCh    
    
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEEC EAX = CCCCCCCC
    
    rep stos    dword ptr [edi]   
    
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEF0 ECX = 0000000F
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEF4 ECX = 0000000E
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FEF8 ECX = 0000000D
    ..
    ..
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FF20 ECX = 00000003
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FF24 ECX = 00000002
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FF28 ECX = 00000001
    
    结束:
    // ESP = 0013FEE0 EBP = 0013FF2C EDI = 0013FF2C ECX = 00000000
    
    EDI 是从低地址向高地址填充的! 


    Keep it simple!
    作者:N3verL4nd
    知识共享,欢迎转载。
  • 相关阅读:
    object-c iOS 教程 git for mac
    mac Git本地服务器配置
    [转]XCode中修改缺省公司名称/开发人员名称
    IOS------Warning
    Linux---CentOS 定时运行脚本配置练手
    微信公众号一些错误的原因错误代码41001
    微信支付的一些新的经验总结
    关于THINKPHP5模型关联的初步理解
    写下thinkphp5和thinkphp3.2的不同
    练手THINKPHP5过程和bootstrap3.3.7
  • 原文地址:https://www.cnblogs.com/lgh1992314/p/5834670.html
Copyright © 2020-2023  润新知