使用内联汇编来实现strcpy的两种思路:
static void _strcpy1( char *dst, char *src )
{
__asm
{
push ecx;
push eax;
push esi;
push edi;
push ebx;
pushfd;
cld;
or ecx, 0xffffffff;
xor eax, eax;
mov edi, dword ptr [ src ];
repne scasb; //使用它SCASB来进行字符串长度的检测
neg ecx; //ECX为字符串长度+1(这个1表示初始的0xffffffff),对其求补码。恰好为字符串+空字符总长度。
//得到字符串长度,为了减少运行次数,如果字符串长度比较长的话,使用movsd+movsb来完成。否则就直接使用movsb来实现。
mov esi, dword ptr [ src ];
mov edi, dword ptr [ dst ];
cmp ecx, 10;
ja multi_mov;
rep movsb;
jmp _return;
multi_mov:
mov ebx, ecx;
shr ecx, 2;
rep movsd; //先以44字节长度的字单位来拷贝,后以1字节单位来拷贝。
mov ecx, ebx;
and ecx, 3;
rep movsb;
_return:
//恢复寄存器退出
popfd;
pop ebx;
pop edi;
pop esi;
pop eax;
pop ecx;
}
printf( "%s/n", dst );
}
static void _strcpy2( char *dst, char *src )
{
__asm
{
push ecx;
push eax;
push esi;
push edi;
pushfd;
cld;
mov esi, dword ptr [ src ];
mov edi, dword ptr [ dst ];
lod_ch:
lodsb; //这次使用了lods和stos指令来完成字符串拷贝,相对效率低一些。如果在其中有一些字符处理的操作的话这段代码就是最合适的。
stosb;
cmp al, 0;
loopne lod_ch;
popfd;
pop edi;
pop esi;
pop eax;
pop ecx;
}
printf( "%s/n", dst );
}
下面是对C语言实现函数和汇编实现函数的性能比较,以memset为例。
这是用一般C代码实现的memset函数
char *memsetc (dst, value, count)
char *dst;
char value;
unsigned int count;
{
while (count--)
*dst++ = value;
return(start);
}
以上C代码生成的汇编码为:
push ebp
mov ebp,esp
sub esp,44h
push ebx
push esi
push edi
//char *start = dst;
mov eax,dword ptr [dst]
mov dword ptr [start],eax
//while (count--)
while (count--)
mov eax,dword ptr [count]
mov ecx,dword ptr [count]
sub ecx,1
mov dword ptr [count],ecx
test eax,eax
je __memsetc+32h (432C12h)
// *dst++ = value;
mov eax,dword ptr [dst]
mov cl,byte ptr [value]
mov byte ptr [eax],cl
mov edx,dword ptr [dst]
add edx,1
mov dword ptr [dst],edx
jmp __memsetc+0Fh (432BEFh)
// return(start);
mov eax,dword ptr [start]
//下面使用内联汇编实现memset功能,比较一下它们的性能特性。
char *__memset( char *mem, int value, unsigned long len )
{
__asm
{
push edx;
mov edx, len;
test edx, edx;
jz short toend;
xor eax, eax;
mov eax, value;
push edi;
mov edi, mem;
cmp edx, 4;
jb tail;
mov ecx, edx;
neg ecx;
and ecx, 3;
jz short dwords;
sub edx, ecx;
adjust_loop:
mov [edi], al;
add edi, 1;
sub ecx, 1;
jnz adjust_loop;
dwords:
movzx ecx, al;
shl eax, 8;
add eax, ecx;
movzx ecx, ax;
shl eax, 10h;
add eax, ecx;
mov ecx, edx;
and edx, 3; //tail bytes
shr ecx, 2; //dwords
jz tail;
rep stosd;
test edx, edx;
jz finish;
tail:
mov [edi], al;
add edi, 1;
sub edx, 1;
jnz tail;
finish:
mov eax, mem;
pop edi;
pop edx;
toend:
mov eax, mem;
pop edx;
};
}
可以看到,如果自己用汇编来实现函数会有很明显的性能提升。