1

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 のドキュメントは非常に曖昧であるため、理解するのはかなり困難です。過去の霧の中で、アセンブラも名前のマングリングを行っていることを思い出しました。

これは、その方法に関する最も明確なリファレンスであり、正確に従っていると思います。それは言います、

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

手がかりはありますか?

ありがとう...

4

2 に答える 2

1

両方のオブジェクトファイルでdumpbinを実行して、シンボルテーブルをダンプしてみてください。これにより、発行された関数名と参照している関数名の両方が表示されます。これは通常、この種の問題を診断するのに役立ちます。

于 2012-08-15T09:24:01.933 に答える
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名前を使用できます。

ドキュメントはALIAShereにあります。あまり印象的ではありません。

でエクスポートされたシンボルを確認できますdumpbin。以下に、Crypto++ プロジェクトの例を示します。

_IF_のように、fastcall 名に不要な先頭のアンダースコアが含まれている場合は、どこかにアンダースコアがない_@InNonSuspendableCriticalRegion@8ことを確認してくださいOPTION LANGUAGE:C

最後に、 とほぼ同等だと思っ たのですが、アセンブラに受け入れてもらうことができませんでした。昔は動いていたのかもしれませんが、最近の Visual Studio では MASM に受け入れさせることができません。SYSCALLFASTCALL


Crypto++ プロジェクトはC++ コードを使用して、fastcall を使用してMASM コードとやり取りします (コードは 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_GenerateBlockが でエクスポートさExternalれ、別名 as で再度エクスポートされ、 で@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
于 2017-03-07T17:18:54.120 に答える