【问题标题】:Assembly sending parameters - fastcall程序集发送参数 - fastcall
【发布时间】:2015-06-24 23:38:27
【问题描述】:

我正在尝试从 c++ 调用我的 asm 函数并发送两个参数,根据维基百科关于 fastcall 调用约定的信息,这些参数应该保存在 ecx 和 edx 中。

但这不起作用。我错过了什么吗?

组装 x86

.model flat

.code
_TestFunction proc

    mov eax, ecx
    add eax, edx
    ret

_TestFunction endp
end

C++ 代码

#include <iostream>

extern "C" int TestFunction(int a, int b);

int main()
{
    std::cout << "Function returns:" << TestFunction(200,100) << std::endl;
    
    std::cin.get();
    return 0;
}

函数返回 1,这是寄存器:

ECX = 00000000 EDX = 00000001

构建日志:

1>----- 重建全部开始:项目:教程,配置:调试 Win32 ------ 1>
组装 asm.asm... 1> 主.cpp 1> Tutorial.vcxproj -> C:\Users\nilo\documents\visual studio 2012\Projects\Tutorial\Debug\Tutorial.exe

==========全部重建:1成功,0失败,0跳过==========

【问题讨论】:

  • 您是否尝试过使用调试器单步执行?
  • 是的,我可以看到寄存器是空的。 ECX = 00000000 EDX = 00000001
  • 您没有声明__fastcall 约定,那么编译器为什么要使用该方法?只需浏览en.wikipedia.org/wiki/X86_calling_conventions
  • 我虽然 MSVS 编译器自动使用了 fastcall?
  • 我想我将 x64 的默认调用约定与 x86 混淆了。为 x64 构建我的项目确实在寄存器中显示了正确的答案,但对于 x86 却没有。我的错,谢谢你的时间。

标签: c++ assembly


【解决方案1】:

如果你真的想要 Win32 中的 __fastcall calling convention,你的代码需要做些小改动:

在汇编文件中,改变

_TestFunction proc
...
_TestFunction endp

@TestFunction@8 proc
...
@TestFunction@8 endp

在 C++ 文件中,更改

extern "C" int TestFunction(int a, int b);

extern "C" int __fastcall TestFunction(int a, int b);

【讨论】:

  • @JoseManuelAbarcaRodríguez:我已经在使用和不使用 VS 2010 Express 的情况下对其进行了测试。它有效。
  • @JoseManuelAbarcaRodríguez。我对file.asm 的“正确”位置有一些问题,但我认为这是由于我缺乏 VS 经验造成的。使用嗅探器(例如filemon)查看ml.exe 在哪里寻找file.asm
  • 嘿,伙计。这实际上解决了 32 位的问题,但我不得不将 @8 更改为 @4。
  • @nilo:后缀 (@8) 是所有参数的大小(以字节为单位)。 "@8" 表示:两个参数 à 4 个字节。如果您需要将其更改为@4,这意味着 VS 确实只识别了一个参数。检查你的源代码!
  • 非常有意义,因为我只发送 1 个整数。干杯伙伴,清除了一切。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-15
  • 2017-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多