如何在另一个函数中获取Delphi代码标签的地址?

如何在另一个函数中获取Delphi代码标签的地址?,delphi,assembly,delphi-5,delphi-xe7,Delphi,Assembly,Delphi 5,Delphi Xe7,我正在尝试将一些代码从Delphi5迁移到DelphiXe7-WIN64。 这个场景是最新的,Delphi不允许混合汇编和Delphi代码。 我也是个新手 原始代码: function TclDbgHelpStackTracer.GetSymbolSearchPath(): string; var sPath: array[0..MAX_PATH] of char; mbi: MEMORY_BASIC_INFORMATION; pProc: Pointer; label l1; be

我正在尝试将一些代码从Delphi5迁移到DelphiXe7-WIN64。 这个场景是最新的,Delphi不允许混合汇编和Delphi代码。 我也是个新手

原始代码:

function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;
var
  sPath: array[0..MAX_PATH] of char;
  mbi: MEMORY_BASIC_INFORMATION;
  pProc: Pointer;
label l1;
begin
  asm
    mov eax, offset l1
    mov pProc, eax
  end;
l1:
  Result := '';
  if (GetEnvironmentVariable(SYMBOL_PATH) <> '') then
Result := GetEnvironmentVariable(SYMBOL_PATH) + ';';
  if (GetEnvironmentVariable(ALTERNATE_SYMBOL_PATH) <> '') then
    Result := Result + GetEnvironmentVariable(ALTERNATE_SYMBOL_PATH) + ';';
  if (GetEnvironmentVariable('SystemRoot') <> '') then
    Result := Result + GetEnvironmentVariable('SystemRoot') + ';';

VirtualQuery(pProc, mbi, sizeof(mbi));
GetModuleFileName(Cardinal(mbi.AllocationBase), sPath, MAX_PATH);
StrRScan(sPath, '\')^ := #0;
Result := Result + sPath + ';';

GetModuleFileName(0, sPath, MAX_PATH);
StrRScan(sPath, '\')^ := #0;
Result := Result + sPath;
end;

问题是如何传递l1的地址?或者还有其他方法可以做到这一点吗?

问题中的代码实际上是在提取包含执行代码的模块的名称。您所需要的就是:

function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;

  function GetEnvPath(const Name: string): string;
  var
    Value: string;
  begin
    Value := GetEnvironmentVariable(Name);
    if Value <> '' then
      Result := Value + ';'
    else
      Result := '';
  end;

  function GetModulePath(Module: HMODULE): string;
  begin
    Result := ExtractFileDir(GetModuleName(Module));
  end;

begin
  Result :=
    GetEnvPath(SYMBOL_PATH) +
    GetEnvPath(ALTERNATE_SYMBOL_PATH) +
    GetEnvPath('SystemRoot') +
    GetModulePath(HInstance) + ';' +
    GetModulePath(0);
end;
函数TclDbgHelpStackTracer.GetSymbolSearchPath():字符串; 函数GetEnvPath(const Name:string):string; 变量 值:字符串; 开始 值:=GetEnvironmentVariable(名称); 如果值为“”,则 结果:=值+';' 其他的 结果:=''; 结束; 函数GetModulePath(模块:HMODULE):字符串; 开始 结果:=ExtractFileDir(GetModuleName(模块)); 结束; 开始 结果:= GetEnvPath(符号路径)+ GetEnvPath(备用符号路径)+ GetEnvPath('SystemRoot')+ GetModulePath(HInstance)+';'+ GetModulePath(0); 结束; 坦率地说,你问题中的
asm
代码很奇怪。没有必要那样做。代码试图做的只是找到模块句柄,该句柄已经作为全局
HInstance
变量可用


一般来说,您应该尽量避免使用
asm
。它使代码的可移植性降低,更难理解。有时使用
asm
是正确的选择。这不是其中一种情况。

卸下asm可获得启发。它还将有助于开始检查错误并停止截断指针。在您进入64位世界之前,您必须认识到指针是64位宽的。正如@rob kennedy在我(现已删除)的回答中所评论的,您可以通过使用全局
HInstance
变量而不是
基数(mbi.AllocationBase)来实现同样的目标
并抛出
pProc
和汇编代码away@xmojmr我没有删除你的答案(我将在周一尝试修复,因为我是OOO。似乎我也丢失了@rob kennedy的评论。我自己删除了答案,因为它只是部分有用。以下是rob的评论:此代码调用
VirtualQuery
以获取基本内存地址。它假定它将是整个DLL的基本地址,并进一步假定基本地址可以代表模块句柄。它传递该“句柄”到
GetModuleFileName
获取DLL的名称。但是DLL在全局
HInstance
变量中已经有了自己的句柄。根本不需要调用
VirtualQuery
。“感谢您的回答。它看起来很完美。我们将在周一检查并接受它作为答案。”。
  VirtualQuery(pProc, mbi, sizeof(mbi));
function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;

  function GetEnvPath(const Name: string): string;
  var
    Value: string;
  begin
    Value := GetEnvironmentVariable(Name);
    if Value <> '' then
      Result := Value + ';'
    else
      Result := '';
  end;

  function GetModulePath(Module: HMODULE): string;
  begin
    Result := ExtractFileDir(GetModuleName(Module));
  end;

begin
  Result :=
    GetEnvPath(SYMBOL_PATH) +
    GetEnvPath(ALTERNATE_SYMBOL_PATH) +
    GetEnvPath('SystemRoot') +
    GetModulePath(HInstance) + ';' +
    GetModulePath(0);
end;