intel编译器编译斐波拉契数列出现的疑问,求指点!!!!
使用icc编译器编译斐波拉契数列,c代码详见下方,得到汇编代码,出现以下疑问:
1。函数入口处保护寄存器时,为何对于esi寄存器入栈两次,而出栈时却对应于esi,ecx,明明没有入栈ecx,而出栈时却多出个ecx,不知有何寓意?
2。icc生成的汇编代码中的注释很多都不知道什么意思,譬如“;2.1”“; LOE eax ebx ebp edi”“; Preds .B1.2”这些都是什么意思呢?
3。在链接时会出错,报错主要是因为生成的asm文件中的一些库文件找不到,我找到的解决办法是,将vc中的这些库手动复制到当前目录下,不过觉得这不是根本解决办法,因该与环境变量的设置有关,不过不太清楚如何修改。
另外,使用命令行模式调用icc时,我想对于生成的汇编代码重命名,譬如:“icl -S -o fibo_111.s fibo.c”,不过在生成汇编文件时好像默认生成的是“fibo.asm”,为什么呢?
1。函数入口处保护寄存器时,为何对于esi寄存器入栈两次,而出栈时却对应于esi,ecx,明明没有入栈ecx,而出栈时却多出个ecx,不知有何寓意?
2。icc生成的汇编代码中的注释很多都不知道什么意思,譬如“;2.1”“; LOE eax ebx ebp edi”“; Preds .B1.2”这些都是什么意思呢?
3。在链接时会出错,报错主要是因为生成的asm文件中的一些库文件找不到,我找到的解决办法是,将vc中的这些库手动复制到当前目录下,不过觉得这不是根本解决办法,因该与环境变量的设置有关,不过不太清楚如何修改。
另外,使用命令行模式调用icc时,我想对于生成的汇编代码重命名,譬如:“icl -S -o fibo_111.s fibo.c”,不过在生成汇编文件时好像默认生成的是“fibo.asm”,为什么呢?
请教大牛指点一二!
c代码:
int fibonacci(int n) { if (n < 2) { return n; } return fibonacci(n - 2) + fibonacci(n - 1); }生成的汇编代码:
; -- Machine type PW ; mark_description "Intel(R) C++ Compiler XE for applications running on IA-32, Version 12.0.0.104 Build 20101006"; ; mark_description "-S"; .686P .387 OPTION DOTNAME ASSUME CS:FLAT,DS:FLAT,SS:FLAT _TEXT SEGMENT PARA PUBLIC FLAT 'CODE' ; COMDAT _fibonacci TXTST0: ; -- Begin _fibonacci ; mark_begin; IF @Version GE 800 .MMX ELSEIF @Version GE 612 .MMX MMWORD TEXTEQU <QWORD> ENDIF IF @Version GE 800 .XMM ELSEIF @Version GE 614 .XMM XMMWORD TEXTEQU <OWORD> ENDIF ALIGN 16 PUBLIC _fibonacci _fibonacci PROC NEAR ; parameter 1: eax .B1.1: ; Preds .B1.0 mov eax, DWORD PTR [4+esp] ;2.1 PUBLIC _fibonacci. _fibonacci.:: push esi ;2.1 push ebp ;2.1 push esi ;2.1 mov ebp, eax ;2.1 cmp ebp, 2 ;2.12 jl .B1.3 ; Prob 5% ;2.12 ; LOE ebx ebp edi .B1.2: ; Preds .B1.1 lea eax, DWORD PTR [-2+ebp] ;6.23 call _fibonacci. ;6.9 ; LOE eax ebx ebp edi .B1.8: ; Preds .B1.2 dec ebp ;6.42 mov esi, eax ;6.9 mov eax, ebp ;6.28 call _fibonacci. ;6.28 ; LOE eax ebx esi edi .B1.7: ; Preds .B1.8 mov ebp, eax ;6.28 add ebp, esi ;6.28 ; LOE ebx ebp edi .B1.3: ; Preds .B1.1 .B1.7 mov eax, ebp ; pop ecx ; pop ebp ; pop esi ; ret ; ALIGN 16 ; LOE ; mark_end; _fibonacci ENDP ;_fibonacci ENDS _TEXT ENDS _DATA SEGMENT DWORD PUBLIC FLAT 'DATA' _DATA ENDS ; -- End _fibonacci _DATA SEGMENT DWORD PUBLIC FLAT 'DATA' _DATA ENDS INCLUDELIB <libmmt> INCLUDELIB <LIBCMT> INCLUDELIB <libirc> INCLUDELIB <svml_disp> INCLUDELIB <OLDNAMES> INCLUDELIB <libdecimal> END
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
那个pop ecx真得很奇怪。。。
估计需要看编译器的约定, 不清楚icc的编译规则
那个pop ecx真得很奇怪。。。
估计需要看编译器的约定, 不清楚icc的编译规则
描述这种关系是用来干什么的呢
回复
注释是给人看的,让你知道从哪些语句能跳转到本段代码。 编译器内部会画DAG图进行编译优化,找到代码间的数据相关、控制相关逻辑
; Preds .B1.1 .B1.7
是描述代码短的前驱关系
.b1.2 这是汇编语句标号,就是地址
2.1应该是对应了C语句行号
编译c程序啊,c代码已经贴出来了~
回复
add esp,4速度慢,pop ecx速度快,ecx是不需要保存的所以一般恢复堆栈都是一句pop ecx.
编译程序还是编译数列。。。。。。。