【问题标题】:MASM x86 fastcall function declaration... how?MASM x86 fastcall 函数声明...怎么样?
【发布时间】:2012-08-12 18:54:42
【问题描述】:

我正在尝试让 VisualStudio 2010 C 程序调用 fastcall 约定汇编例程。

这是C代码中的声明:

extern boolean _fastcall InNonSuspendableCriticalRegion(DWORD);

这是汇编代码中的声明:

      public @InNonSuspendableCriticalRegion@4

  @InNonSuspendableCriticalRegion@4 proc near ; fastcall
         <code>
  @InNonSuspendableCriticalRegion@4 endp

我收到以下链接器错误:

   Assembling: C:\DMS\Domains\PARLANSE\Tools\RunTimeSystem\Source\PARLANSE0.asm
   1>RuntimeSupport.obj : error LNK2001: unresolved external symbol @InNonSuspendableCriticalRegion@4

我确定我做错了什么傻事,但我看不到。

MS 文档很难弄清楚,因为它非常模糊。我记得在过去的迷雾中,汇编器也会进行一些名称修改,所以我不确定如何 如果是的话,我提供的名称会被破坏。

这是关于如何操作的most explicit reference,我想我完全遵循它;它说,

13. FASTCALL Caller and Callee Summary

The following sample illustrates the code generated in the calling function and in the called function to support __fastcall, the fastcall calling convention:

   int __fastcall FastFunc( int a, int b );

      calling function    called function
      -------------------------------------------
      mov edx, b          @FastFunc@8 PROC NEAR
      mov ecx, a                       .
      call @FastFunc@8                 .
       .                               .
       .                              RET 8
       .                  @FastFunc@8 ENDP

有什么线索吗?

谢谢...

【问题讨论】:

  • C 代码以剪切-粘贴形式显示。您认为问题出在单“_”上吗?好的,我也对 MS 约定感到困惑,因为“_fastcall”是合法的并且被 C 编译器接受。
  • ...我在 C 声明中尝试了“__fastcall”。行为上没有区别。
  • 使用额外选项进行组装以生成地图文件怎么样?它应该包含实际的符号(名称)。
  • 此外,您应该能够在PROC 指令中指定调用约定,请参阅PROC's langtype option.MODEL's langtypes 的列表。这应该会产生适当的名称修饰并让您访问 PROC 的参数(当然,如果已声明)。

标签: assembly x86 declaration masm fastcall


【解决方案1】:

尝试在两个目标文件上运行 dumpbin 以转储符号表。这应该同时显示发出的和引用的函数名称。这通常有助于诊断这类问题。

【讨论】:

    【解决方案2】:

    这是汇编代码中的声明:

    public @InNonSuspendableCriticalRegion@4
    
    @InNonSuspendableCriticalRegion@4 proc near ; fastcall
         ;; code
    @InNonSuspendableCriticalRegion@4 endp
    

    我认为你很接近。这个答案中唯一真正的见解是汇编程序默认情况下不会损坏,所以如果你调用你的过程InNonSuspendableCriticalRegion,那么它就是这样导出的。要为更高级别的语言获得一个错误的名称,您通常可以按照 Alexey 的建议进行操作。但是没有FASTCALL,所以只需使用ALIAS

    改为这样做:

    title Really cool assembly routines
    public InNonSuspendableCriticalRegion
    
    .486
    .MODEL FLAT
    
    .CODE
    ALIGN   8
    
    ALIAS <@InNonSuspendableCriticalRegion@4> = <InNonSuspendableCriticalRegion>
    
    OPTION PROLOGUE:NONE
    OPTION EPILOGUE:NONE
    
    InNonSuspendableCriticalRegion proc
        ;; code
    InNonSuspendableCriticalRegion endp
    
    OPTION PROLOGUE:PrologueDef
    OPTION EPILOGUE:EpilogueDef
    
    ;; ...
    
    end
    

    认为 public @InNonSuspendableCriticalRegion@4 也不正确(但它不是名称装饰问题的原因)。您可以省略它,也可以使用未修饰的InNonSuspendableCriticalRegion 名称。

    您可以找到ALIAS here 的文档。这不是很令人印象深刻。

    您可以使用dumpbin 查看导出了哪些符号。下面有一个来自 Crypto++ 项目的示例。

    _IF_ 您在 fastcall 名称中得到一个 不需要的 前导下划线,例如 _@InNonSuspendableCriticalRegion@8,然后确保您不要' t 在某处有一个OPTION LANGUAGE:C

    最后,我认为 SYSCALL 基本上等同于FASTCALL,但我无法让汇编程序接受它。也许它在过去可以工作,但我无法让 MASM 用现代 Visual Studio 接受它。


    Crypto++项目使用C++ code通过fastcall与MASM code接口(代码调用RDRAND或RDSEED,需要快速运行)。

    C++ 代码

    以下声明同时用于 X86 和 X64。

    #if MASM_RDRAND_ASM_AVAILABLE
    extern "C" void CRYPTOPP_FASTCALL MASM_RDRAND_GenerateBlock(byte*, size_t);
    #endif
    
    #if MASM_RDSEED_ASM_AVAILABLE
    extern "C" void CRYPTOPP_FASTCALL MASM_RDSEED_GenerateBlock(byte*, size_t);
    #endif
    

    垃圾箱

    请注意符号MASM_RDRAND_GenerateBlockExternal 导出,并以别名@MASM_RDRAND_GenerateBlock@8 再次导出并以WeakExternal 显示。

    如果您没有行符号(标签),请务必使用/Zi 组装。它是您的带有 MASM 文件的调试信息。

    C:\>dumpbin /SYMBOLS rdrand-x86.obj
    
    Dump of file rdrand-x86.obj
    
    File Type: COFF OBJECT
    
    COFF SYMBOL TABLE
    000 00DF520D ABS    notype       Static       | @comp.id
    001 00000011 ABS    notype       Static       | @feat.00
    002 00000000 SECT1  notype       Static       | .text$mn
        Section length   6F, #relocs    0, #linenums    0, checksum        0
    004 00000000 SECT2  notype       Static       | .data
        Section length    0, #relocs    0, #linenums    0, checksum        0
    006 00000000 SECT3  notype       Static       | .debug$S
        Section length  534, #relocs   26, #linenums    0, checksum        0
    008 00000000 SECT4  notype       Static       | .debug$T
        Section length   3C, #relocs    0, #linenums    0, checksum        0
    00A 00000000 SECT1  notype ()    External     | MASM_RDRAND_GenerateBlock
    00B 00000000 UNDEF  notype       WeakExternal | @MASM_RDRAND_GenerateBlock@8
        Default index        A Alias record
    00D 00000038 SECT1  notype ()    External     | MASM_RDSEED_GenerateBlock
    00E 00000038 UNDEF  notype       WeakExternal | @MASM_RDSEED_GenerateBlock@8
        Default index        D Alias record
    010 00000000 SECT1  notype       Static       | $$000000
    011 00000000 SECT1  notype       Label        | GenerateBlock_Top
    012 00000005 SECT1  notype       Label        | Call_RDRAND_EAX
    013 0000000A SECT1  notype       Label        | RDRAND_succeeded
    014 0000000F SECT1  notype       Label        | Full_Machine_Word
    015 00000019 SECT1  notype       Label        | Partial_Machine_Word
    016 0000002A SECT1  notype       Label        | Bit_1_Not_Set
    017 00000034 SECT1  notype       Label        | Bit_0_Not_Set
    018 00000034 SECT1  notype       Label        | GenerateBlock_Return
    019 00000038 SECT1  notype       Label        | GenerateBlock_Top
    01A 0000003D SECT1  notype       Label        | Call_RDSEED_EAX
    01B 00000042 SECT1  notype       Label        | RDSEED_succeeded
    01C 00000047 SECT1  notype       Label        | Full_Machine_Word
    01D 00000051 SECT1  notype       Label        | Partial_Machine_Word
    01E 00000062 SECT1  notype       Label        | Bit_1_Not_Set
    01F 0000006C SECT1  notype       Label        | Bit_0_Not_Set
    020 0000006C SECT1  notype       Label        | GenerateBlock_Return
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-21
      • 2014-07-09
      • 1970-01-01
      • 2014-12-28
      • 2013-10-10
      • 1970-01-01
      相关资源
      最近更新 更多