【问题标题】:INVOKE MASM saving registers automatically?INVOKE MASM 自动保存寄存器?
【发布时间】:2010-11-16 09:08:12
【问题描述】:

当我在 masm 中使用 Invoke 指令时,是否可以自动保存 cpu 寄存器?

【问题讨论】:

    标签: assembly masm masm32


    【解决方案1】:

    看看我在那里发布的例子:selection sort in assembly language

    目标 PROC 中的 USES 指令就是您要查找的内容。
    使用 EAX ESI EDI 将在 PROC 进入时自动保存这些寄存器并在退出时恢复它们(即使您有多个 RET 点,即使不推荐使用多个 ret 点)。 IOW,它将在 PROC 进入时生成 PUSH,并在每个 RET 之前生成一致匹配(倒序)的 POP。这个想法是,由于这是汇编,您可以完全控制和负责您修改想要保留的那些寄存器。
    与其他地方的建议相反,声明 stdcall 不会在 MASM 中自动为您保留任何内容。它只是确定调用者(为 INVOKE 生成的代码)或被调用者(在 PROC 中生成的代码)是否弹出参数。

    【讨论】:

    • 这个问题是关于invoke,而不是proc。或者你的意思是你可以使用usesinvoke
    • INVOKE 的唯一用途是调用带有调用约定、参数等的 PROC。
    • INVOKE 是一个围绕调用、处理调用约定、参数等的 HLL 包装器。INVOKE 和 PROC 扩展是同一枚硬币的两个方面。例如,根据 proc 类型,参数将由调用者(在返回时,因此由 INVOKE 生成)或被调用者(在每个 RET 之前的 proc 内)删除。除了这个之外,没有其他方法可以在 MASM 中自动保存/恢复注册表。否则,对于每个调用,它都是手动的,在调用之前通过 PUSHing 并在返回时弹出。
    • @filofel:“INVOKE 的唯一用途是调用 PROC”——真的吗?那么导入的函数调用呢?我可以写invoke GetCommandLineproc 在哪里?什么会保留我的寄存器?
    • @abyx:没有内置方法可以在调用点“自动”执行此操作。唯一的方法是直接或通过宏或通过调用将执行此操作的包装器 fnc 然后调用 GetCommandLine() 在调用周围推送/弹出寄存器,但这些绝不是“自动的”。关键是保存寄存器的一般方法是在被调用者内部而不是来自调用者,只要保存/恢复指令在函数中存在一次而不是在每个调用点都存在(这是使用 stdcall 的原因,这比 cdecl 更好)。
    【解决方案2】:

    "stdcall" 调用约定保证函数不会破坏除 eax、edx、ecx 之外的任何寄存器。如果你想保存 edx 和 ecx - 写一个宏。

    【讨论】:

    • 有什么办法可以强制 eax 在 INVOKE 期间自动保存然后自动恢复?
    • @Jumbo 你可以写宏来保存它,但是当你恢复它时你会丢失函数返回值。
    • stdcall 实际上并不保证 MASM 中的任何内容。它可能充其量建议该函数应该以这种方式运行。要自动保存/恢复寄存器,您必须在 PROC 定义中使用USES 指令。查看我的回复。
    【解决方案3】:

    不确定你的意思,因为你的标签是 masm32,我假设是 Windows x86。

    完全可能的是推送 API 调用所需的所有参数,然后您只需调用所需的函数。我的意思是,当您在 Windows 的程序集中进行 promming 时,您不需要使用寄存器来“调用”API,您必须推送参数然后调用(或调用)API。

    例如,这个:

    push 0
    push DWORD PTR SS:[EBP+8]
    push 0
    push 0
    push 80000000h
    push 80000000h
    push 80000000h
    push 80000000h
    push 0CF0000h
    push offset AppName
    push offset ClassName
    push 0h
    call CreateWindowExA
    

    正好等于这个(其实只是参数的值不同):

    invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
    

    你的问题就是这个意思吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多