0

我正在研究用Visual Studio 2008编译的一些代码的反汇编,并且我发现在代码中发现一些奇怪的“优化”,在调用函数时不太合理并传递参数。例如,下面的代码输出以下拆解:未知的编译器“优化”没有意义

代码:

int version; 
int result = canParse(code, &version);` 

拆卸:

003CE9FA push eax    ; version 
003CE9FB push ecx    ; code 
003CE9FC mov  ecx, [esp+50h+code] ; AbcParser * 
003CEA00 mov  eax, esp 
003CEA02 mov  [eax], ecx 
003CEA04 call avmplus::AbcParser::canParse(avmplus::ScriptBuffer,int *) 

在这种情况下,push ecx使得堆栈中的部分空间然后被[esp+50h+code]覆盖。

为什么编译器会这样做?

它不节省空间。 (需要更少的空间才能拥有mov ecx, [esp+50h+code]; push ecx。)据我所知,这并不能节省时间。 (不会执行刚刚提到的两条指令会更快吗?)

此外,在canParse中使用ecxeax时都会被覆盖。

+1

也许它是更多的指令,但更少的时钟周期? – 2011-04-21 19:32:19

+0

@drhirsch:他是对的:'mov ecx,[esp + 50h + code]; mov eax,esp; mov [eax],ecx'与mov [esp],[esp + 50h + code]相同(我知道它是非法寻址模式),因此覆盖上次推动的东西 – BlackBear 2011-04-22 11:57:46

+0

@BlackBear:像“push dword [esp + 50h + code]“是有效的,可以替代4条指令。我也会试图假设“优化器不完美”比“更多指令但更少循环”更可能。 – Brendan 2011-04-22 12:33:27

回答

0

正如@Radek Pro-Grammer在他的评论中所建议的那样,即使有更多的指令看起来毫无用处,代码可能会在更少的时钟周期内运行。现在的处理器要复杂得多,有流水线,预取队列,缓存,超标量设计等等,所以优化可以相当大胆。 :)