|
http://blog.csdn.net/pony_maggie/article/details/6748662 总看到网上一些人说指针访问比数组访问效率高, 但很少人解释其中的原理, 这篇文章从汇编级别上分析一下原因. 我用一个"reverse"函数来作为例子, 分别用指针和数组的形式来实现这个函数. view plain -
- void reverse(char *pStr,int nLen)
- {
- char *pStart=pStr;
- char *pEnd=pStr+nLen-1;
- char chTmp;
-
- while(pEnd > pStart)
- {
- chTmp = *pStart;
- *pStart = *pEnd;
- *pEnd = chTmp;
-
- pStart++;
- pEnd--;
- }
- }
这是上面的函数在vc6下的反汇编代码,我加了一些注释方便理解 view plain - 19: void reverse(char *pStr,int nLen)
- 20: {
- 00401070 push ebp
- 00401071 mov ebp,esp
- 00401073 sub esp,4Ch
- 00401076 push ebx
- 00401077 push esi
- 00401078 push edi
- 00401079 lea edi,[ebp-4Ch]
- 0040107C mov ecx,13h
- 00401081 mov eax,0CCCCCCCCh
- 00401086 rep stos dword ptr [edi]
-
- 00401088 mov eax,dword ptr [ebp+8]
- 0040108B mov dword ptr [ebp-4],eax
-
- 0040108E mov ecx,dword ptr [ebp+0Ch]
- 00401091 mov edx,dword ptr [ebp+8]
- 00401094 lea eax,[edx+ecx-1]
- 00401098 mov dword ptr [ebp-8],eax
-
- 0040109B mov ecx,dword ptr [ebp-8]
- 0040109E cmp ecx,dword ptr [ebp-4]
- 004010A1 jbe reverse+61h (004010d1)
-
- 004010A3 mov edx,dword ptr [ebp-4]
- 004010A6 mov al,byte ptr [edx]
- 004010A8 mov byte ptr [ebp-0Ch],al
-
- 004010AB mov ecx,dword ptr [ebp-4]
- 004010AE mov edx,dword ptr [ebp-8]
- 004010B1 mov al,byte ptr [edx]
- 004010B3 mov byte ptr [ecx],al
-
- 004010B5 mov ecx,dword ptr [ebp-8]
- 004010B8 mov dl,byte ptr [ebp-0Ch]
- 004010BB mov byte ptr [ecx],dl
-
- 004010BD mov eax,dword ptr [ebp-4]
- 004010C0 add eax,1
- 004010C3 mov dword ptr [ebp-4],eax
-
- 004010C6 mov ecx,dword ptr [ebp-8]
- 004010C9 sub ecx,1
- 004010CC mov dword ptr [ebp-8],ecx
- }
view plain -
- void reverse(char *pStr,int nLen)
- {
- int i = 0;
- int j = nLen-1;
- char chTmp;
-
- while(j>i)
- {
- chTmp=pStr[i];
- pStr[i]=pStr[j];
- pStr[j]=chTmp;
-
- i++;
- j--;
- }
- }
这是上面代码的反汇编 view plain - 19: void reverse(char *pStr,int nLen)
- 20: {
- 004010D0 push ebp
- 004010D1 mov ebp,esp
- 004010D3 sub esp,4Ch
- 004010D6 push ebx
- 004010D7 push esi
- 004010D8 push edi
- 004010D9 lea edi,[ebp-4Ch]
- 004010DC mov ecx,13h
- 004010E1 mov eax,0CCCCCCCCh
- 004010E6 rep stos dword ptr [edi]
-
- 004010E8 mov dword ptr [ebp-4],0
-
- 004010EF mov eax,dword ptr [ebp+0Ch]
- 004010F2 sub eax,1
- 004010F5 mov dword ptr [ebp-8],eax
-
- 004010F8 mov ecx,dword ptr [ebp-8]
- 004010FB cmp ecx,dword ptr [ebp-4]
- 004010FE jle reverse+6Ah (0040113a)
-
- 00401100 mov edx,dword ptr [ebp+8]
- 00401103 add edx,dword ptr [ebp-4]
- 00401106 mov al,byte ptr [edx]
- 00401108 mov byte ptr [ebp-0Ch],al
-
- 0040110B mov ecx,dword ptr [ebp+8]
- 0040110E add ecx,dword ptr [ebp-4]
- 00401111 mov edx,dword ptr [ebp+8]
- 00401114 add edx,dword ptr [ebp-8]
- 00401117 mov al,byte ptr [edx]
- 00401119 mov byte ptr [ecx],al
-
- 0040111B mov ecx,dword ptr [ebp+8]
- 0040111E add ecx,dword ptr [ebp-8]
- 00401121 mov dl,byte ptr [ebp-0Ch]
- 00401124 mov byte ptr [ecx],dl
-
- 00401126 mov eax,dword ptr [ebp-4]
- 00401129 add eax,1
- 0040112C mov dword ptr [ebp-4],eax
-
- 0040112F mov ecx,dword ptr [ebp-8]
- 00401132 sub ecx,1
- 00401135 mov dword ptr [ebp-8],ecx
- }
两个函数反汇编后的代码基本是一致的,但第二段汇编中多了几个add语句, 这是因为在用数组下标的形式访问字符串时,总要对数组的首地址做加减操作才能定位到想要的值, 而指针的实现则一开始就copy了一个首地址,不需要再用加减来定位.显然在这个例子中,用指针来实现reverse函数效率要高.
|