通过指针进行迭代和通过索引进行迭代是否产生相同代码
2005-03-04 11:31
691 查看
编译器对通过指针进行迭代和通过索引进行迭代是否产生相同代码?问题来自于《The C++ Program Language》第五章习题8。
测试代码如下:(采用vc.net向导自动生成控制台应用程序)
#include "stdafx.h"
void fi (char v[]) // line 5
{
for (int i = 0; v[i] != 0; ++i) {
v[i] += 1;
}
}
void fp (char v[]) // line 12
{
for (char *p=v; *p != 0; ++p) {
*pa += 1;
}
}
int _tmain(int argc, _TCHAR* argv[]) // line 19
{
char
a[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g' , 'h'};
fp (a);
fi (a);
return 0;
}
在vc++7.net上使用参数FA(仅列出程序集),产生的汇编代码如下(未优化):
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077
TITLE ./5_8.cpp .386Pinclude listing.inc... ... ... ...INCLUDELIB LIBCDINCLUDELIB OLDNAMES
PUBLIC ?fi@@YAXQAD@Z ; fi,函数fi的代码开始EXTRN __RTC_InitBase:NEAREXTRN __RTC_Shutdown:NEAR; COMDAT rtc$IMZ; File d:/vsproject/5_8/5_8.cpprtc$IMZ SEGMENT__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBasertc$IMZ ENDS; COMDAT rtc$TMZrtc$TMZ SEGMENT__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown; Function compile flags: /Odt /RTCsu /ZIrtc$TMZ ENDS; COMDAT ?fi@@YAXQAD@Z_TEXT SEGMENT_i$10435 = -8 ; size = 4_v$ = 8 ; size = 4?fi@@YAXQAD@Z PROC NEAR ; fi, COMDAT; Line 6 push ebp mov ebp, esp sub esp, 204 ; 000000ccH push ebx push esi push edi lea edi, DWORD PTR [ebp-204] mov ecx, 51 ; 00000033H mov eax, -858993460 ; ccccccccH rep stosd; Line 7 // ******************************** mov DWORD PTR _i$10435[ebp], 0 jmp SHORT $L10436$L10437: mov eax, DWORD PTR _i$10435[ebp] add eax, 1 mov DWORD PTR _i$10435[ebp], eax$L10436: mov eax, DWORD PTR _v$[ebp] add eax, DWORD PTR _i$10435[ebp] movsx ecx, BYTE PTR [eax] test ecx, ecx je SHORT $L10434; Line 8 mov eax, DWORD PTR _v$[ebp] add eax, DWORD PTR _i$10435[ebp] movsx ecx, BYTE PTR [eax] add ecx, 1 mov edx, DWORD PTR _v$[ebp] add edx, DWORD PTR _i$10435[ebp] mov BYTE PTR [edx], cl; Line 9 jmp SHORT $L10437$L10434:; Line 10 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0?fi@@YAXQAD@Z ENDP ; fi_TEXT ENDS
PUBLIC ?fp@@YAXQAD@Z ; fp,函数fp的代码开始; Function compile flags: /Odt /RTCsu /ZI; COMDAT ?fp@@YAXQAD@Z_TEXT SEGMENT_p$10442 = -8 ; size = 4_v$ = 8 ; size = 4?fp@@YAXQAD@Z PROC NEAR ; fp, COMDAT; Line 13 push ebp m
fc31
ov ebp, esp sub esp, 204 ; 000000ccH push ebx push esi push edi lea edi, DWORD PTR [ebp-204] mov ecx, 51 ; 00000033H mov eax, -858993460 ; ccccccccH rep stosd; Line 14 // ****************************** mov eax, DWORD PTR _v$[ebp] mov DWORD PTR _p$10442[ebp], eax jmp SHORT $L10443$L10444: mov eax, DWORD PTR _p$10442[ebp] add eax, 1 mov DWORD PTR _p$10442[ebp], eax$L10443: mov eax, DWORD PTR _p$10442[ebp] movsx ecx, BYTE PTR [eax] test ecx, ecx je SHORT $L10441; Line 15 mov eax, DWORD PTR _p$10442[ebp] movsx ecx, BYTE PTR [eax] add ecx, 1 mov edx, DWORD PTR _p$10442[ebp] mov BYTE PTR [edx], cl; Line 16 jmp SHORT $L10444$L10441:; Line 17 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0?fp@@YAXQAD@Z ENDP ; fp_TEXT ENDS
PUBLIC _mainEXTRN @_RTC_CheckStackVars@8:NEAREXTRN __RTC_CheckEsp:NEAR; Function compile flags: /Odt /RTCsu /ZI; COMDAT _main... ... ... ...END注意上面Line8和Line15前后的汇编语句,就是一模一样的。也就是说,在没有任何优化的情况下,通过指针进行迭代和通过索引进行迭代将产生相同代码。
如果进行全面的优化,结果会怎么样呢?对同一个文件,在vc7.net采用RELEASE,打开全局优化,产生的汇编代码如下。可以看到,两个函数的代码仍然是相同的。
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077
TITLE ./5_8.cpp .386Pinclude listing.inc... ... ... ...INCLUDELIB LIBCINCLUDELIB OLDNAMES
PUBLIC ?fi@@YAXQAD@Z ; fi,函数fi的代码开始; Function compile flags: /Ogty; COMDAT ?fi@@YAXQAD@Z_TEXT SEGMENT_v$ = 8 ; size = 4?fi@@YAXQAD@Z PROC NEAR ; fi, COMDAT; File d:/vsproject/5_8/5_8.cpp; Line 7 mov eax, DWORD PTR _v$[esp-4] cmp BYTE PTR [eax], 0 je SHORT $L9624 npad 7$L9622:; Line 8 inc BYTE PTR [eax] mov cl, BYTE PTR [eax+1] inc eax test cl, cl jne SHORT $L9622$L9624:; Line 10 ret 0?fi@@YAXQAD@Z ENDP ; fi_TEXT ENDS
PUBLIC ?fp@@YAXQAD@Z ; fp,函数fp的代码开始; Function compile flags: /Ogty; COMDAT ?fp@@YAXQAD@Z_TEXT SEGMENT_v$ = 8 ; size = 4?fp@@YAXQAD@Z PROC NEAR ; fp, COMDAT; Line 14 mov eax, DWORD PTR _v$[esp-4] cmp BYTE PTR [eax], 0 je SHORT $L9631 npad 7$L9629:; Line 15 inc BYTE PTR [eax] mov cl, BYTE PTR [eax+1] inc eax test cl, cl jne SHORT $L9629$L9631:; Line 17 ret 0?fp@@YAXQAD@Z ENDP ; fp_TEXT ENDS
PUBLIC _mainEXTRN ___security_cookie:DWORDEXTRN @__security_check_cookie@4:NEAR; Function compile flags: /Ogty; COMDAT _main... ... ... ...END
测试代码如下:(采用vc.net向导自动生成控制台应用程序)
#include "stdafx.h"
void fi (char v[]) // line 5
{
for (int i = 0; v[i] != 0; ++i) {
v[i] += 1;
}
}
void fp (char v[]) // line 12
{
for (char *p=v; *p != 0; ++p) {
*pa += 1;
}
}
int _tmain(int argc, _TCHAR* argv[]) // line 19
{
char
a[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g' , 'h'};
fp (a);
fi (a);
return 0;
}
在vc++7.net上使用参数FA(仅列出程序集),产生的汇编代码如下(未优化):
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077
TITLE ./5_8.cpp .386Pinclude listing.inc... ... ... ...INCLUDELIB LIBCDINCLUDELIB OLDNAMES
PUBLIC ?fi@@YAXQAD@Z ; fi,函数fi的代码开始EXTRN __RTC_InitBase:NEAREXTRN __RTC_Shutdown:NEAR; COMDAT rtc$IMZ; File d:/vsproject/5_8/5_8.cpprtc$IMZ SEGMENT__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBasertc$IMZ ENDS; COMDAT rtc$TMZrtc$TMZ SEGMENT__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown; Function compile flags: /Odt /RTCsu /ZIrtc$TMZ ENDS; COMDAT ?fi@@YAXQAD@Z_TEXT SEGMENT_i$10435 = -8 ; size = 4_v$ = 8 ; size = 4?fi@@YAXQAD@Z PROC NEAR ; fi, COMDAT; Line 6 push ebp mov ebp, esp sub esp, 204 ; 000000ccH push ebx push esi push edi lea edi, DWORD PTR [ebp-204] mov ecx, 51 ; 00000033H mov eax, -858993460 ; ccccccccH rep stosd; Line 7 // ******************************** mov DWORD PTR _i$10435[ebp], 0 jmp SHORT $L10436$L10437: mov eax, DWORD PTR _i$10435[ebp] add eax, 1 mov DWORD PTR _i$10435[ebp], eax$L10436: mov eax, DWORD PTR _v$[ebp] add eax, DWORD PTR _i$10435[ebp] movsx ecx, BYTE PTR [eax] test ecx, ecx je SHORT $L10434; Line 8 mov eax, DWORD PTR _v$[ebp] add eax, DWORD PTR _i$10435[ebp] movsx ecx, BYTE PTR [eax] add ecx, 1 mov edx, DWORD PTR _v$[ebp] add edx, DWORD PTR _i$10435[ebp] mov BYTE PTR [edx], cl; Line 9 jmp SHORT $L10437$L10434:; Line 10 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0?fi@@YAXQAD@Z ENDP ; fi_TEXT ENDS
PUBLIC ?fp@@YAXQAD@Z ; fp,函数fp的代码开始; Function compile flags: /Odt /RTCsu /ZI; COMDAT ?fp@@YAXQAD@Z_TEXT SEGMENT_p$10442 = -8 ; size = 4_v$ = 8 ; size = 4?fp@@YAXQAD@Z PROC NEAR ; fp, COMDAT; Line 13 push ebp m
fc31
ov ebp, esp sub esp, 204 ; 000000ccH push ebx push esi push edi lea edi, DWORD PTR [ebp-204] mov ecx, 51 ; 00000033H mov eax, -858993460 ; ccccccccH rep stosd; Line 14 // ****************************** mov eax, DWORD PTR _v$[ebp] mov DWORD PTR _p$10442[ebp], eax jmp SHORT $L10443$L10444: mov eax, DWORD PTR _p$10442[ebp] add eax, 1 mov DWORD PTR _p$10442[ebp], eax$L10443: mov eax, DWORD PTR _p$10442[ebp] movsx ecx, BYTE PTR [eax] test ecx, ecx je SHORT $L10441; Line 15 mov eax, DWORD PTR _p$10442[ebp] movsx ecx, BYTE PTR [eax] add ecx, 1 mov edx, DWORD PTR _p$10442[ebp] mov BYTE PTR [edx], cl; Line 16 jmp SHORT $L10444$L10441:; Line 17 pop edi pop esi pop ebx mov esp, ebp pop ebp ret 0?fp@@YAXQAD@Z ENDP ; fp_TEXT ENDS
PUBLIC _mainEXTRN @_RTC_CheckStackVars@8:NEAREXTRN __RTC_CheckEsp:NEAR; Function compile flags: /Odt /RTCsu /ZI; COMDAT _main... ... ... ...END注意上面Line8和Line15前后的汇编语句,就是一模一样的。也就是说,在没有任何优化的情况下,通过指针进行迭代和通过索引进行迭代将产生相同代码。
如果进行全面的优化,结果会怎么样呢?对同一个文件,在vc7.net采用RELEASE,打开全局优化,产生的汇编代码如下。可以看到,两个函数的代码仍然是相同的。
; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077
TITLE ./5_8.cpp .386Pinclude listing.inc... ... ... ...INCLUDELIB LIBCINCLUDELIB OLDNAMES
PUBLIC ?fi@@YAXQAD@Z ; fi,函数fi的代码开始; Function compile flags: /Ogty; COMDAT ?fi@@YAXQAD@Z_TEXT SEGMENT_v$ = 8 ; size = 4?fi@@YAXQAD@Z PROC NEAR ; fi, COMDAT; File d:/vsproject/5_8/5_8.cpp; Line 7 mov eax, DWORD PTR _v$[esp-4] cmp BYTE PTR [eax], 0 je SHORT $L9624 npad 7$L9622:; Line 8 inc BYTE PTR [eax] mov cl, BYTE PTR [eax+1] inc eax test cl, cl jne SHORT $L9622$L9624:; Line 10 ret 0?fi@@YAXQAD@Z ENDP ; fi_TEXT ENDS
PUBLIC ?fp@@YAXQAD@Z ; fp,函数fp的代码开始; Function compile flags: /Ogty; COMDAT ?fp@@YAXQAD@Z_TEXT SEGMENT_v$ = 8 ; size = 4?fp@@YAXQAD@Z PROC NEAR ; fp, COMDAT; Line 14 mov eax, DWORD PTR _v$[esp-4] cmp BYTE PTR [eax], 0 je SHORT $L9631 npad 7$L9629:; Line 15 inc BYTE PTR [eax] mov cl, BYTE PTR [eax+1] inc eax test cl, cl jne SHORT $L9629$L9631:; Line 17 ret 0?fp@@YAXQAD@Z ENDP ; fp_TEXT ENDS
PUBLIC _mainEXTRN ___security_cookie:DWORDEXTRN @__security_check_cookie@4:NEAR; Function compile flags: /Ogty; COMDAT _main... ... ... ...END
相关文章推荐
- JS判断来路是否是百度等搜索索引进行弹窗或自动跳转的实现代码
- 通过索引或指针对数组元素进行访问
- JS通过相同的name进行表格求和代码
- 基于X.509证书和SSL协议的身份认证过程实现(OpenSSL可以自己产生证书,有TCP通过SSL进行实际安全通讯的实际编程代码)good
- 类的相同通过对是否为同一个类加载器进行判断
- JS通过相同的name进行表格求和代码
- const修饰的常量 不能被直接修改 但是可以通过指针进行间接修改
- 快速排序中对指针地址所指向的值进行排序的代码
- 通过模板判断Value是否为指针
- 对WM_NCHITTEST消息的了解+代码实例进行演示(消息产生消息,共24个枚举值)
- 数据表记录包含表索引和数值,请对表索引相同的记录进行合并,即将相同索引的数值进行求和运算,输出按照key值升序进行输出。
- js判断来路是否是百度等搜索索引进行弹窗或自动跳转
- 如何通过代码加密对服务器安全进行保护?
- cxf整合Spring框架进行服务端开发,并且通过cxf生成客户端代码进行调用
- 产生n位数序列如果不够n位的数字前边用0补齐,通过 bash而且不用循环,直接产生n个相同的字符组成的字符串
- 通过下拉框的值来确定输入框是否可以为空的代码
- CXF客户端配置请求超时限制-SocketTimeoutException(Spring配置文件中配置和通过代码进行配置)
- 定义两个整型指针,分别用malloc、calloc对其分配空间保存3个元素,malloc分配的空间用memset清零,随机对数组进行赋值随机范围1-3,赋值后用memcmp比较两个数组。如果相同打印G
- android中控制根据是否选中或者按下改变按钮的颜色(通过xml代码实现)
- 今天通过对HDWiki程序代码分析进行啦head部分的搜索SEO