部分C庫函數重寫以及反彙編分析之memmov()

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

功能:由src所指內存區域複製count個字節到dest所指內存區域。   
說明:src和dest所指內存區域可以重疊,但複製後dest內容會被更改。函數返回指向dest的指針。
 
/////////////////////////////////////////////////////////////////////////////////////*/
#include "stdafx.h"

void *pmemmove(void *dest , void *src , int count);

int main(int argc, char* argv[])
{
	//printf("Hello World!\n");
	char a1[]="abcdefg";
	char a2[10]={0};

	printf("%s\n",a2);

	pmemmove(a2,a1,5);

	printf("%s\n",a2);
	return 0;
}

void *pmemmove(void *dest , void *src , int count)
{
	char *temp_dest=(char *)dest;
	char *temp_src=(char *)src;

	if (temp_dest<temp_src || temp_src+count<temp_dest)
	{
		// 沒有重疊區域
		//從高地址拷貝到低地址
		while (count--)
		{
			*temp_dest=*temp_src;
			temp_src++;
			temp_dest++;
		}
		
	}
	else
	{
		//有重疊區域
		temp_src=temp_src+count-1;
		temp_dest=temp_dest+count-1;

		while(count--)
		{
			*temp_dest=*temp_src;
			temp_src--;
			temp_dest--;
		}
	}
	
	return dest;
}

這個函數主要考慮到2段內存區域是否重疊。

判斷是否重疊的邏輯分析如下圖:


release模式編譯,OD載入反彙編分析如下:

00401000  /$  83EC 14       sub esp,14
00401003  |.  A1 34704000   mov eax,dword ptr ds:[407034]
00401008  |.  8B0D 38704000 mov ecx,dword ptr ds:[407038]            ;  abcdefg賦值,存在eax/ecx中
0040100E  |.  33D2          xor edx,edx                              ;  edx=0
00401010  |.  894424 00     mov dword ptr ss:[esp],eax               ;  a1=abcdefg
00401014  |.  895424 09     mov dword ptr ss:[esp+9],edx             ;  a2[]={0};
00401018  |.  8D4424 08     lea eax,dword ptr ss:[esp+8]             ;  eac存放a2首地址
0040101C  |.  895424 0D     mov dword ptr ss:[esp+D],edx
00401020  |.  50            push eax
00401021  |.  68 30704000   push memmove.00407030                    ;  ASCII "%s
"
00401026  |.  894C24 0C     mov dword ptr ss:[esp+C],ecx
0040102A  |.  C64424 10 00  mov byte ptr ss:[esp+10],0
0040102F  |.  885424 19     mov byte ptr ss:[esp+19],dl
00401033  |.  E8 78000000   call memmove.004010B0
00401038  |.  8D4C24 08     lea ecx,dword ptr ss:[esp+8]             ;  abcdefg存入ecx
0040103C  |.  6A 05         push 5
0040103E  |.  8D5424 14     lea edx,dword ptr ss:[esp+14]            ;  將數組a2首地址存入edx
00401042  |.  51            push ecx
00401043 >|.  52            push edx                                 ;  三個參數依次入棧
00401044  |.  E8 17000000   call memmove.00401060                    ;  調用函數(memmove)
00401049  |.  8D4424 1C     lea eax,dword ptr ss:[esp+1C]
0040104D  |.  50            push eax
0040104E  |.  68 30704000   push memmove.00407030                    ;  ASCII "%s
"
00401053  |.  E8 58000000   call memmove.004010B0
00401058  |.  33C0          xor eax,eax
0040105A  |.  83C4 30       add esp,30
0040105D  \.  C3            retn
0040105E      90            nop
0040105F      90            nop
00401060  /$  8B4424 04     mov eax,dword ptr ss:[esp+4]             ;  將第一個參數(從左往右)存入eax(memmove函數的入口處)
00401064  |.  8B4C24 0C     mov ecx,dword ptr ss:[esp+C]             ;  將第三個參數存入ecx  (5)
00401068  |.  56            push esi
00401069  |.  8B7424 0C     mov esi,dword ptr ss:[esp+C]             ;  esi=abcdefg;
0040106D  |.  3BC6          cmp eax,esi                              ;  參數1和參數2進行比較  這裏esi存的是abcd首地址
0040106F  |.  57            push edi
00401070  |.  8BD0          mov edx,eax
00401072  |.  72 24         jb short memmove.00401098                ;  參數1<=參數2,則跳
00401074  |.  8D3C0E        lea edi,dword ptr ds:[esi+ecx]
00401077  |.  3BF8          cmp edi,eax                              ;  這裏edi存的是“fg”字符串首地址
00401079  |.  72 1D         jb short memmove.00401098                ;  dest<src,跳
0040107B  |.  8D57 FF       lea edx,dword ptr ds:[edi-1]
0040107E  |.  8D7408 FF     lea esi,dword ptr ds:[eax+ecx-1]
00401082  |.  8BF9          mov edi,ecx
00401084  |.  49            dec ecx
00401085  |.  85FF          test edi,edi
00401087  |.  74 24         je short memmove.004010AD
00401089  |.  8D79 01       lea edi,dword ptr ds:[ecx+1]
0040108C  |>  8A0A          /mov cl,byte ptr ds:[edx]
0040108E  |.  4A            |dec edx
0040108F  |.  880E          |mov byte ptr ds:[esi],cl
00401091  |.  4E            |dec esi
00401092  |.  4F            |dec edi
00401093  |.^ 75 F7         \jnz short memmove.0040108C
00401095  |.  5F            pop edi
00401096  |.  5E            pop esi
00401097  |.  C3            retn
00401098  |>  8BF9          mov edi,ecx                              ;  進入while(n--)循環,開始拷貝內存數據
0040109A  |.  49            dec ecx
0040109B  |.  85FF          test edi,edi
0040109D  |.  74 0E         je short memmove.004010AD
0040109F  |.  2BF0          sub esi,eax
004010A1  |.  8D79 01       lea edi,dword ptr ds:[ecx+1]
004010A4  |>  8A0C16        /mov cl,byte ptr ds:[esi+edx]
004010A7  |.  880A          |mov byte ptr ds:[edx],cl
004010A9  |.  42            |inc edx
004010AA  |.  4F            |dec edi
004010AB  |.^ 75 F7         \jnz short memmove.004010A4
004010AD  |>  5F            pop edi
004010AE  |.  5E            pop esi
004010AF  \.  C3            retn

表示反彙編功底太差,看得我要死。。。。。。。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章