【问题标题】:C++ inline assembly function not working properlyC++ 内联汇编函数无法正常工作
【发布时间】:2010-08-21 12:13:30
【问题描述】:

我每次都得到不同的返回值,所以我做错了。如果我将 add 替换为基本的 inc,它会正确返回。

这里是代码。

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <iostream>

using namespace std;

int Add ( int _Number1, int _Number2 );

int main ( int _ArgumentCount, char * _Arguments[] )
{
    int nInput, nOutput;

    nOutput = Add ( 1, 1 );

    cout << "1 + 1 = " << nOutput << endl;
    cin >> nInput;

    return 0;
}

__declspec ( naked ) int Add ( int _Number1, int _Number2 )
{
    __asm   xor eax, eax
    __asm   mov eax, _Number1
    __asm   add eax, _Number2
    __asm   ret
}

这是新的工作代码:

#define WIN32_LEAN_AND_MEAN

#include <Windows.h>
#include <iostream>

using namespace std;

int Add ( int Number1, int Number2 );

int main ( int ArgumentCount, char * Arguments[] )
{
    int nInput, nOutput;

    nOutput = Add ( 1, 1 );

    cout << "1 + 1 = " << nOutput << endl;
    cin >> nInput;

    return 0;
}

int Add ( int Number1, int Number2 )
{
    __asm   mov eax, Number1
    __asm   add eax, Number2
}

【问题讨论】:

  • 你怎么知道_Number1 不是eax?允许编译器调用带有寄存器中参数的函数。我认为你的问题是你没有做出任何努力来避免通过声明你使用的寄存器等来避免踩到编译器的脚趾。看看你的程序反汇编来证明。
  • 你为什么使用__declspec(naked)?你确定你需要这样做吗?如果不这样做会怎样?
  • @Borealid - 这是我的第一次尝试,不太确定我在做什么。我认为 EAX 是为返回值保留的,我应该使用哪些寄存器? @Greg - 没有它会有一些编译问题。谷歌搜索,论坛上一个人说要使用裸声明。

标签: c++ inline-assembly


【解决方案1】:

__declspec (naked) 表示该函数是在没有任何 prolog 或 epilog 代码的情况下创建的——因此,如果您想访问形式参数,您需要编写自己的 prolog 代码来访问它们。您的 xor 也一事无成,因为您立即用另一个值覆盖 eax。另请注意,任何以下划线后跟大写字母开头的标识符都是保留的,因此您的代码具有未定义的行为。尝试将您的函数重写为:

int Add ( int number1, int number2 )
{
    __asm   mov eax, number1
    __asm   add eax, number2
}

或者编写代码来访问堆栈上的参数而不依赖于序言:

__declspec (naked) int Add2(int number1, int number2) { 
    _asm mov eax, [esp+4]
    _asm add eax, [esp+8]
    _asm ret
}

我没有检查,但我猜您的原始代码试图从 [ebp+8] 和 [ebp+12] 加载参数。这取决于正常的序言代码:

push ebp
mov ebp, esp

...您的__declspec (naked) 专门告诉编译器 生成。

【讨论】:

  • 非常感谢。我承认,当它没有编译时,我找到了赤裸裸的“解决方案”,我什至没有读进去。我很懒。我也不知道保留的名称。非常感谢,我现在可以正常工作了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-28
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多