zoukankan      html  css  js  c++  java
  • 汇编实现: C库常见函数,串操作指令作用

    汇编实现: C库常见函数

    一丶汇编实现Strncpy拷贝函数

    void __asmStrncpy(char *des,char *src,int len)
    {
    	__asm {
         mov edi,[ebp + 8];                //获取局部变量地址 des
         mov esi,[ebp + 0xc];            //获取局部变量地址 src
         mov ecx,len;                    //使用movs指令,需要给ecx长度
         cld                                //设置DF = 0; 内存方向, 此时edi++ esi ++获取方式
         rep movs byte ptr [edi],byte ptr[esi];//根据ecx的值,循环从esi里面获取字节输几局给edi
         ;rep movsb                        //直接省略了.默认操作 eis 跟 edi.以字节方式
         ;rep movsw                        //以word两个字节为单位拷贝 等价于 rep movs byte ptr[edi],byte ptr[esi]
         ;rep movsd                        //四个字节为单位.
    
    	}
    
    }
    

    总结:

    movs指令的作用
    主要使用了串操作指令movs指令 [esi] 拷贝->[edi] ecx计数 rep重复.

      1.跟ecx搭配, ecx控制循环次数

      2.跟cld搭配. cld设置DF位,这样拷贝的时候内存就是++拷贝

      3.movs的主要作用就是把 esi所指向的内存数据 拷贝到 edi所指向的内存中.

      4.movs 有很多重载, 例如 movsb movsw movsd 分别就是按照字节拷贝, 按照一个字拷贝 按照4个字拷贝.

    二丶loads实现Strlen操作.

    loads作用: 将 [esi]所指向内存拷贝到 eax中/ax al..

    	int __asmStrlen(char *src)
    {
    
    	__asm{
    		mov esi,[ebp + 8];  //获取src参数地址给esi
    		xor eax,eax;
    		xor ebx,ebx;        //清空计数寄存器
    Len:
    		Lods byte ptr[esi]; //将esi内存的字符串按照1字节给eax存储
    		test eax,eax;		//判断最后的eax是否为0
    		jz Exit;			//为0 就把计数的值给eax进行返回
    		inc ebx;   			//不为0,计数器++
    		jnz len; 			//并且跳转到上边继续执行. 
    Exit:
    		mov eax,ebx;
    	}
    }
    

    总结:

    lods 主要就是[esi] 内存的值给eax进行存储. 其lodsb lodsd lodsw 分别就是按照一个字节 两个字节 4个字节赋值.
    1.lods寄存器 操作的 esi 跟 eax寄存器
    2.eax存放从esi里面获取的数据按照 lodsb lodsd losw等指令拷贝一个字节还是多个字节
    3.loads 是通用的,后面只需要给定你拷贝的字节个数即可. 例如 lods byte ptr[esi] word ptr[esi]

    三丶stos的作用

    stos作用于 edi,和 eax. 把eax的值拷贝到edi所指向的内存中.
    根据ecx的长度决定,配合rep指令.
    相应的也有
    stosb
    stosw
    stosd

    __declspec(naked) int RetValue()
    {
    	__asm
    	{	
    		push ebp;				;保存栈低,老ebp
    		mov ebp,esp				;老ebp等于当前的栈顶,便于寻址
    		sub esp,0x20;			;开辟局部变量空间
    		lea edi,[esp];			;取得栈顶地址,进行拷贝.首先获取一下,否则如果写在下方则要 ebp - xxx进行获取局部变量空间
    		pushad					;保存寄存器环境
    		mov ecx,0x20			;赋值ecx 0x20个字节. rep循环20次.以byte 的形式
    		mov eax,0xcc;			;eax给cc,进行初始化
    		rep stos byte ptr[edi]; ;根据ecx个数,将局部eax的值赋值到edi中,给局部变量初始化为cc
    		popad					;恢复寄存器环境
    		mov esp,ebp				;恢复局部变量空间, 栈顶跟原栈顶一样.
    		pop ebp					;恢复栈低.
    		ret						;返回.
    	}
    }
    
    

    总结

    总结来说. stos(stosb sw sd)就是把eax的值,拷贝到edi所指向的内存中,使用rep循环指令.拷贝大小.
    1.获取局部变量空间.
    2.给eax赋值你要初始化的值
    3.给ecx赋值,计数的值
    4.rep 配合stos将 eax值赋值给edi所指向的内存

  • 相关阅读:
    实验证明:ObjectiveC++ 完美支持 ARC
    用 Java 实现的日志切割清理工具
    数字电视,方便了谁
    商品EAN13条码的生成
    关于错误“Cannot connect to the Citrix MetaFrame server.Can't assign requested address”的解决方法
    "加载类型库/dll时出错" 的解决方法
    解决连接SQL Server 2000的TCP/IP错误的Bug
    电脑自动关机之CPU风扇烧坏
    winrar 8 注册方法
    电脑死机之CPU温度过高
  • 原文地址:https://www.cnblogs.com/iBinary/p/9835948.html
Copyright © 2011-2022 走看看