几个字符串操作的汇编函数

//------------------------------------------------------------------------

#pragma once

namespace wch
{
 //取得字符串结束符指针
 __declspec(naked)
 char * __stdcall strend(const char *src)
 { __asm
  { mov ecx,[esp+4] //ecx=src
 misaligned:
   test ecx,3
   jz main_loop
   mov al,[ecx]
   inc ecx
   test al,al
   jnz misaligned
   lea eax,[ecx-1]
   ret 4
 align   4
 main_loop:
   mov eax,[ecx]
   add ecx,4
   mov edx,7efefeffh
   add edx,eax
   xor eax,-1
   xor eax,edx
   test eax,80010100h
   je main_loop
   mov eax,[ecx-4]
   test al,al
   jz is_0
   test ah,ah
   jz is_1
   bswap eax
   test ah,ah
   jz is_2
   lea eax,[ecx-1]
   ret 4
 is_0:
   lea eax,[ecx-4]
   ret 4
 is_1:
   lea eax,[ecx-3]
   ret 4
 is_2:
   lea eax,[ecx-2]
   ret 4
  }
 };

 //求字符串长度,等于字节数
 inline int strlen(const char *src)
 { return strend(src)-src;
 };

 //拷贝字符串,注意源串与目标串不可重叠!
 __declspec(naked)
 int __stdcall strcpy(const char *src,char *dst)
 { __asm
  { push esi
   push edi

   mov esi,[esp+12] //esi=src
   mov edi,[esp+16] //edi=dst
   jmp isaligned
 misaligned:
   mov [edi],al
   inc edi
 isaligned:
   test esi,3
   jz start
   mov al,[esi]
   inc esi
   test al,al
   jnz misaligned
 finished:
   mov eax,edi
   sub eax,[esp+16]
   pop edi
   pop esi
   ret 8
 align   4
 main_loop:
   mov [edi],ecx
   add edi,4
 start:
   mov eax,[esi]
   mov ecx,eax
   add esi,4
   mov edx,7efefeffh
   add edx,eax
   xor eax,-1
   xor eax,edx
   test eax,80010100h
   je main_loop

   test cl,cl
   jz is_0
   test ch,ch
   jz is_1
   mov eax,ecx
   bswap ecx
   test ch,ch
   jz is_2
   mov [edi],eax
   add edi,3
   jmp finished
 is_0:
   mov [edi],cl
   jmp finished
 is_1:
   mov [edi],cx
   add edi,1
   jmp finished
 is_2:
   mov [edi],ax
   add edi,2
   mov [edi],ch
   jmp finished
  }
 };

 //链接拷贝字符串,注意源串与目标串不可重叠
 inline int strcat(const char *src,char *dst)
 { return strcpy(src,strend(dst));
 };

 //将字符串置为某一字符的重复序列
 __declspec(naked)
 void __stdcall strset(char *dst,int ch)
 { __asm
  { push edi

   mov edi,[esp+8]  //edi=dst
   mov al,[esp+12]  //al=ch
   mov ah,al
   mov cx,ax
   shl ecx,16
   mov cx,ax   //ecx=ch,ch,ch,ch

   jmp isaligned
 misaligned:
   mov [edi],cl
   inc edi
 isaligned:
   test edi,3
   jz start
   mov al,[edi]
   test al,al
   jnz misaligned
 finished:
   pop edi
   ret 8

 align   4
 main_loop:
   mov [edi],ecx
   add edi,4
 start:
   mov eax,[edi]
   mov edx,7efefeffh
   add edx,eax
   xor eax,-1
   xor eax,edx
   test eax,80010100h
   je main_loop

   mov eax,[edi]
   test al,al
   jz finished
   test ah,ah
   jz is_1
   shl eax,16
   test ch,ch
   jz is_2
   mov [edi],cx
   mov [edi+2],cl
   jmp finished
 is_1:
   mov [edi],cl
   jmp finished
 is_2:
   mov [edi],cx
   jmp finished
  }
 };

 //将目标内存置为某一字符的重复序列
 __declspec(naked)
 void __stdcall memset(void *dst,int len,int ch)
 { __asm
  { mov edx,[esp+4]  //edx=dst
   mov al,[esp+12]  //al=ch
   mov ah,al
   mov cx,ax
   shr eax,16
   mov ax,cx   //eax=ch,ch,ch,ch

   mov ecx,[esp+8]  //ecx=len
   jmp isaligned
 misaligned:
   mov [edx],al
   inc edx
   dec ecx
 isaligned:
   test edx,3
   jz start
   test ecx,ecx
   jnz misaligned

   ret 12
   
 align   4
 main_loop:
   mov [edx],eax
   add edx,4
 start:
   sub ecx,4
   jge main_loop

   add ecx,4
   jmp isfinshed
 sub_loop:
   mov [edx],al
   inc edx
   dec ecx
 isfinshed:
   test ecx,ecx
   jnz sub_loop

   ret 12
  }
 };

 //内存复制,注意源与目标不能重叠!
 __declspec(naked)
 int __stdcall memcpy(const void *src,int len,void *dst)
 { __asm
  { push esi

   mov esi,[esp+8]  //esi=src
   mov edx,[esp+16] //edx=dst
   mov ecx,[esp+12] //ecx=len
   jmp isaligned
 misaligned:
   mov al,[esi]
   inc esi
   mov [edx],al
   inc edx
   dec ecx
 isaligned:
   test esi,3
   jz start
   test ecx,ecx
   jnz misaligned
 finished:
   mov eax,esi
   sub eax,[esp+8]
   pop esi
   ret 12

 align   4
 main_loop:
   mov eax,[esi]
   add esi,4
   mov [edx],eax
   add edx,4
 start:
   sub ecx,4
   jge main_loop

   add ecx,4
   jmp isfinshed
 sub_loop:
   mov al,[esi]
   inc esi
   mov [edx],al
   inc edx
   dec ecx
 isfinshed:
   test ecx,ecx
   jnz sub_loop

   jmp finished
  }

 };

};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值