我正在尝试使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
任何线索?
...谢谢
答案 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_GenerateBlock
与External
一起导出,并再次导出,别名为@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