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

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

函數解釋:將s中前n個字節替換爲ch並返回s;   
memset:作用是在一段內存塊中填充某個給定的值,它是對較大的結構體或數組進行清零操作的一種最快方法。

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

#include "stdafx.h"

void *pmemset(void *s , char ch , int n);

int main(int argc, char* argv[])
{
	char a[20];
	printf("%s\n",a);
	pmemset(a,'a',10);
	printf("%s\n",a);
	return 0;
}

void *pmemset(void *s , char ch , int n)
{
	char *temp_s=(char *)s;
	while (n--)
	{
		*temp_s=ch;
		temp_s++;
	}

	return s;
}

代碼很簡單,每天堅持,確實可以感受到明顯的進步,特備是反彙編分析能力。加油!!

release編譯,OD載入分析如下:

在release編譯模式下,rep stos 配合填充,可以使dword 、byte快速初始化。

00401000  /$  83EC 14       sub esp,14                               ;  開闢14h(20)字節大小的內存空間留個變量(數組a[20])
00401003  |.  8D4424 00     lea eax,dword ptr ss:[esp]               ;  eax存放地址a
00401007  |.  50            push eax                                 ;  地址a入棧
00401008  |.  68 30704000   push memset.00407030                     ;  ASCII "%s
"
0040100D  |.  E8 6E000000   call memset.00401080                     ;  printf
00401012  |.  6A 0A         push 0A                                  ;  參數3:10 入棧
00401014  |.  8D4C24 0C     lea ecx,dword ptr ss:[esp+C]             ;  ecx存放地址a
00401018  |.  6A 61         push 61                                  ;  ‘a’入棧
0040101A  |.  51            push ecx                                 ;  地址a入棧
0040101B  |.  E8 20000000   call memset.00401040                     ;  memset()
00401020  |.  8D5424 14     lea edx,dword ptr ss:[esp+14]
00401024  |.  52            push edx
00401025  |.  68 30704000   push memset.00407030                     ;  ASCII "%s
"
0040102A  |.  E8 51000000   call memset.00401080
0040102F  |.  33C0          xor eax,eax
00401031  |.  83C4 30       add esp,30
00401034  \.  C3            retn
00401035      90            nop
00401036      90            nop
00401037      90            nop
00401038      90            nop
00401039      90            nop
0040103A      90            nop
0040103B      90            nop
0040103C      90            nop
0040103D      90            nop
0040103E      90            nop
0040103F      90            nop
00401040  /$  8B4424 0C     mov eax,dword ptr ss:[esp+C]             ;  memset入口地址  eax存int n=0ah
00401044  |.  8BC8          mov ecx,eax                              ;  while(n--)
00401046  |.  48            dec eax
00401047  |.  85C9          test ecx,ecx
00401049  |.  74 30         je short memset.0040107B
0040104B  |.  8D48 01       lea ecx,dword ptr ds:[eax+1]             ;  ecx=n-1
0040104E  |.  8A4424 08     mov al,byte ptr ss:[esp+8]               ;  al存‘a’
00401052  |.  53            push ebx
00401053  |.  8AD8          mov bl,al
00401055  |.  8AFB          mov bh,bl                                ;  bh='a'
00401057  |.  56            push esi
00401058  |.  8B7424 0C     mov esi,dword ptr ss:[esp+C]             ;  esi存放地址a
0040105C  |.  8BC3          mov eax,ebx                              ;  'a'存入eax
0040105E  |.  8BD1          mov edx,ecx                              ;  edx=n-1
00401060  |.  57            push edi
00401061  |.  C1E0 10       shl eax,10                               ;  eax邏輯左移10h位
00401064  |.  8BFE          mov edi,esi                              ;  edi存放地址a
00401066  |.  66:8BC3       mov ax,bx
00401069  |.  C1E9 02       shr ecx,2                                ;  ecx右移2位 ecx爲後面重複次數 ecx=10b
0040106C  |.  F3:AB         rep stos dword ptr es:[edi]              ;  將ax值重複存放到目的串符號地址(地址a),即填充,一次填充8個a
0040106E  |.  8BCA          mov ecx,edx
00401070  |.  83E1 03       and ecx,3                                ;  ecx=2
00401073  |.  F3:AA         rep stos byte ptr es:[edi]               ;  填充了2個a  此處是以byte填充的
00401075  |.  8BC6          mov eax,esi
00401077  |.  5F            pop edi
00401078  |.  5E            pop esi
00401079  |.  5B            pop ebx
0040107A  |.  C3            retn
0040107B  |>  8B4424 04     mov eax,dword ptr ss:[esp+4]
0040107F  \.  C3            retn


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