0

我通过以下代码在 c 文件中使用程序集创建了一个自我异常处理程序:

__asm 
    {
        pushad
        mov esi, offset Handler 
        push esi 
        push dword ptr fs:[0] 
        mov dword ptr fs:[0], esp
        push u32Param
        call pFunc;
        jmp NoException

Handler:

        mov esp, [esp + 8]
        pop dword ptr fs:[0]
        add esp, 4
        popad
        mov eax, 0x80000000     
        jmp ExceptionHandled

NoException:

        pop dword ptr fs:[0]
        add esp, 40

ExceptionHandled:
    }

这段代码是汇编中的简单异常处理。
此代码适用于新创建的 vc 项目。
但在我的项目中,它产生了一个异常,vc 说有一个无效的异常处理程序。

有什么建议吗?

4

1 回答 1

2

如果您正在关注这篇文章,那么您为什么不正确地恢复堆栈,如代码中所示?

文章中的代码:

18  NoException&;Handler:                ;;No Exception Occured
19      pop dword ptr fs:[0]            ;;Restore Old Exception Handler
20      add esp, 32 + 4                 ;;ESP value before SEH was set. 32 for pushad and ...
21  ExceptionHandled&;Handler:           ;;...4 for push offset Handler. (No Restore State)
22                                      ;;Exception has been handled, or no exception occured

你的代码:

NoException:

        pop dword ptr fs:[0]
        add esp, 8

ExceptionHandled:

该代码中的 32 是撤消pushad,4 是撤消push esi。为什么你有 8 个?32 + 4 ≠ 8。

如果这就是您想要u32Param从堆栈中删除的方式(以防pFunc不适合您),那么您应该在这两行之间进行:

    call pFunc;
    add esp, 4
    jmp NoException

我的版本:

// file: tst.c
// compile with Open Watcom C/C++ 1.9: wcl386.exe /q /we /wx tst.c
// ditto with debug info: wcl386.exe /q /we /wx /d2 tst.c
#include <stdio.h>

unsigned __stdcall func(volatile unsigned* p)
{
  return *p;
}

unsigned blah(unsigned (__stdcall *pFunc)(volatile unsigned*), volatile unsigned* u32Param)
{
  unsigned result = 0;

  __asm 
  {
      pushad
//      mov esi, offset Handler // Open Watcom C/C++ says Handler is undefined
//      push esi 

//      lea eax, blah
//      add eax, Handler - blah // this difference doesn't come out correct with Open Watcom C/C++
//      add eax, 78 // 78 is Handler - blah // this is unreliable
//      push eax

      push 0xFDCB4321
      jmp GetHandlerAddr
  GotHandlerAddr:
      pop eax
      add esp, 4
      push eax

      push dword ptr fs:[0] 
      mov dword ptr fs:[0], esp
      push u32Param
      call dword ptr [pFunc]

      jmp NoException

  GetHandlerAddr:
      call Handler // this will place &Handler on the stack
  Handler:
      cmp dword ptr [esp + 4], 0xFDCB4321
      je GotHandlerAddr

      mov esp, [esp + 8]
      pop dword ptr fs:[0]
      add esp, 4
      popad
      mov eax, 0x80000000     
      jmp ExceptionHandled

  NoException:

      pop dword ptr fs:[0]
      add esp, 32 + 4

  ExceptionHandled:

      mov result, eax
  }

  return result;
}

int main(void)
{
  volatile unsigned n = 0x113355AA;
  printf("%08X\n", func(&n));
  printf("%08X\n", blah(&func, &n));
  printf("%08X\n", blah(&func, (volatile unsigned*)0));
  printf("%08X\n", blah(&func, (volatile unsigned*)0));
  return 0;
}

输出:

113355AA
113355AA
80000000
80000000
于 2013-04-13T07:50:57.130 回答