我查看了启用了所有优化的发布版本的 ASM 代码,这是我遇到的内联函数之一:
0061F854 mov eax,[$00630bec]
0061F859 mov eax,[$00630e3c]
0061F85E mov edx,$00000001
0061F863 mov eax,[eax+edx*4]
0061F866 cmp byte ptr [eax],$01
0061F869 jnz $0061fa83
该代码很容易理解,它将偏移量 (1) 构建到表中,将其中的字节值与 1 进行比较,如果为 NZ,则执行跳转。我知道指向我的表的指针存储在 $00630e3c 中,但我不知道 $00630bec 的来源。
为什么有两个动作一个接一个?第一个不是被第二个覆盖了吗?这可能是缓存优化的事情,还是我错过了一些令人难以置信的明显/模糊的东西?
上述 ASM 的 Delphi 代码如下:
if( TGameSignals.IsSet( EmitParticleSignal ) = True ) then [...]
IsSet() 是一个内联类函数,调用 TSignalManager 的内联 IsSet() 函数:
class function TGameSignals.IsSet(Signal: PBucketSignal): Boolean;
begin
Result := FSignalManagerInstance.IsSet( Signal );
end;
信号管理器的最终 IsSet 是这样的:
function TSignalManagerInstance.IsSet( Signal: PBucketSignal ): Boolean;
begin
Result := Signal.Pending;
end;