Mas*_*ler 6 delphi assembly basm
我正在研究JIT编译器,并试图找出如何为托管类型(如字符串)输出正确的清理块.
对于具有一个类型的局部变量的函数,清理块的反汇编string如下所示:
0044333C 648910 mov fs:[eax],edx
0044333F 6854334400 push $00443354
00443344 8D45FC lea eax,[ebp-$04]
00443347 E81834FCFF call @UStrClr
0044334C C3 ret
0044334D E9062BFCFF jmp @HandleFinally
00443352 EBF0 jmp $00443344
Run Code Online (Sandbox Code Playgroud)
不幸的是,我没有什么好办法来获得的地址,@UStrClr并@HandleFinally让我的抖动插入.它们在System.Pas中声明为_UStrClr和_HandleFinally,在接口部分,但显然有一些"魔术"正在进行,因为尝试使用这些标识符会导致编译器错误.
所以我尝试了一个ASM例程,在那里我声明了一个全局指针并说mov func_ustr_clear, @UStrClear.这次我没有得到未声明的标识符错误; 我得到一些更奇怪的东西:
[DCC Error]: E2107 Operand size mismatch
Run Code Online (Sandbox Code Playgroud)
所以有人知道如何做到这一点吗?
试试这些函数来获取的地址UStrClr和HandleFinally:
function GetUStrClrAddress: Pointer;
asm
{$IFDEF CPUX64}
mov rcx, offset System.@UStrClr;
mov @Result, rcx;
{$ELSE}
mov @Result, offset System.@UStrClr;
{$ENDIF}
end;
function GetHandleFinallyAddress: Pointer;
asm
{$IFDEF CPUX64}
mov rcx, offset System.@HandleFinally;
mov @Result, rcx;
{$ELSE}
mov @Result, offset System.@HandleFinally;
{$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)
编辑:
@ArnaudBouchez也建议进一步优化.通过直接将值放入函数返回寄存器,该函数更快一些.
function GetUStrClrAddress: Pointer;
asm
{$ifdef CPU64}
mov rax,offset System.@UStrClr
{$else}
mov eax,offset System.@UStrClr
{$endif}
end;
Run Code Online (Sandbox Code Playgroud)
在Delphi中汇编使用的进一步阅读可以在这里找到(和使用的OFFSET关键字)Assembly Expressions, Expression Classes.