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

我正在尝试从Delphi 5移植一些代码到Delphi XE7-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;

上面的代码在Delphi XE7-WIN32中工作但是正如你所看到的,上面的代码片段嵌套了asm块Delphi XE7-WIN64要求程序/函数只包含asm或pascal代码。 所以我将它改为:

{$IFDEF WIN64}
procedure AsmProc(pProc: Pointer);
asm
mov eax, offset l1
mov pProc, eax
end;
{$ENDIF}

function TclDbgHelpStackTracer.GetSymbolSearchPath(): string;
var
  sPath: array[0..MAX_PATH] of char;
  mbi: MEMORY_BASIC_INFORMATION;
  pProc: Pointer;
label l1;
begin
{$IFDEF WIN32}
  asm
    mov eax, offset l1
    mov pProc, eax
  end;
{$ELSE}
    AsmProc(pProc);
{$ENDIF}
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是代码标签,它的地址(下一个可执行语句的地址)被移动到eax,然后指针pProc指向这个地址。 然后使用指针pProc

  VirtualQuery(pProc, mbi, sizeof(mbi));

问题是如何传递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;

坦率地说,你问题中的asm代码很奇怪。 没有必要这样做。 所有的代码试图做的是找到已经可用作为全局HInstance变量的模块句柄。

作为一般规则,您应该尽量避免使用asm 。 它使得代码不易移植并且难以理解。 有时候使用asm是正确的选择。 这不是其中之一。

链接地址: http://www.djcxy.com/p/89889.html

上一篇: How to get address of Delphi code label in another function?

下一篇: Indirect Addressing and Arrays