MASM x86 fastcall函数声明......怎么样?

时间:2012-08-12 18:54:43

标签: assembly x86 declaration masm fastcall

我正在尝试使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

任何线索?

...谢谢

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

  

这是汇编代码中的声明:

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 _ 您在快速呼叫名称中获得不需要的前导下划线,例如_@InNonSuspendableCriticalRegion@8,然后确保不要在某个地方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

<强> DUMPBIN

请注意,符号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