【问题标题】:D7: Read var-arguments after call proc with asm 32-bit stdcallD7:使用 asm 32 位 stdcall 调用 proc 后读取 var-arguments
【发布时间】:2020-06-09 19:06:56
【问题描述】:

你好,使用下面的代码用 asm 调用函数,调用后读取结果。这很好用。现在,-如何阅读之后的论点变化,最好的问候

//push arguments:
  for i:=lst.cnt downto 0 do begin //reverse order
   ia:=longword(lst.fList^[i]);
   asm push ia end;   //push 32-Bit argument
  end;
  asm
   call proc     //call the routine
   mov ia, eax   //get result right after the call
  end;
//how to read variable arguments here ?

编辑:

初始代码已经运行了一段时间,没有任何问题,即使使用循环也是如此。这个问题的原因来了,当我不得不像这样调用一个winapi例程时:

function GetWindowRect(hWnd: HWND; var lpRect: TRect): BOOL; stdcall;
external user32 name 'GetWindowRect';

它声明了一个可变记录参数“lpRect”(大小:16 字节)。我试图在调用之前(推送)这 4 个整数,然后在调用后读取它们。结果表明只是传递了一个指针到在这种情况下实际工作的数据。

结论:所以没有变量参数,只有指向值或记录的指针。感谢您提供任何有助于得出此结论的意见

【问题讨论】:

  • "ia" 包含结果(有效),如果它们被过程更改,想读取在调用之前通过“push”传递的所有参数
  • 根据调用约定 STDCALL,它们可能仍在堆栈中。尝试mov ecx, [esp-4]mov ecx, [esp-8] 等来检索以前的参数。
  • 您的代码是偶然的。在循环中使用“push”asm 是非常危险的。这取决于调用约定...proc 不能是具有注册调用约定的常规 Delphi 函数。
  • @zx485 非常感谢会尝试这样做,会回来的。
  • @Arnaud Bouchez 是的,现在总是使用stdcall(dll)来调用winapi,并且在循环之前准备好参数。必须使用循环,因为输入的参数数量可能会有所不同

标签: delphi dll x86 inline-assembly function-call


【解决方案1】:

如果按值传递参数,则list.fList^[i] 包含指向该值的指针。

只需取消引用并使用它,例如 PInteger(list.fList^[i])^ 用于通过引用传递的整数参数(如 var)。

但请注意,您的代码非常糟糕,并且在循环中使用 push 非常危险。它还需要遵循调用约定——使用默认 Delphi 寄存器定义的proc 函数将其第一个参数传递到 eax/ecx/edx。检查this reference material - 您的问题似乎表明您对它的工作原理有点困惑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-11
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 1970-01-01
    相关资源
    最近更新 更多