如何调用C ++函数在我的组装code [英] How to call C++ functions in my assembly code

查看:116
本文介绍了如何调用C ++函数在我的组装code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要打电话PrintResult从我的组装来显示结果。我知道我必须从某个地方使用EXTRN _PrintResult,我就用电话_PrintResult调用函数,但我不知道很清楚如何使用它。任何建议

 公共_Square.386.MODEL平。code_Square PROCMOV EAX,[ESP + 4]IMUL EAXRET_Square ENDP

.............这里是我的C ++ code .........

 的#include<&iostream的GT;使用命名空间std;枚举结果code {ShowSquare};
枚举成功code {失败,成功};为externC珑坊(长);无效的主要()
 {
 长NUM1;
         长NUM2; 做
  {
  COUT<< 输入号码来坊<< ENDL;
  CIN>> NUM1;
  结果=广场(NUM1);
  COUT<< 广场:<<结果<< ENDL;
  }而(结果大于0);
 }无效PrintResult(结果code打印code,长值)//打印code,长值)
 {
 开关(打印code)
  {
  案例ShowSquare:
    COUT<< 方形的显示是:<<价值与LT;< ENDL;
    打破;  默认:
    COUT<< 错误汇编程序<< ENDL;
  }
}


解决方案

我平时不喜欢张贴满code东西,但试试这个:

32位汇编​​

  .386
.MODEL平
。code_Square PROC
MOV EAX,[ESP + 4]
IMUL EAX推EAX;保存计算结果;这里叫PrintResult
推EAX;值
推0; ShowSquare
调用_PrintResult
ADD ESP,8;清除栈流行EAX;返回计算结果RET
_Square ENDP

C ++

 的#include<&iostream的GT;使用命名空间std;枚举结果code {ShowSquare};
枚举成功code {失败,成功};为externC珑坊(长);INT主(INT ARGC,CHAR *的argv [])
{
    长NUM1,NUM2;    做
    {
        COUT<< 输入数字方<< ENDL;
        CIN>> NUM1;
        NUM2 =广场(NUM1);
        COUT<< 方回:<< NUM2<< ENDL;
    }
    而(NUM2);    返回0;
}为externC
无效PrintResult(结果code测试结果,长值)
{
    开关(结果)
    {
        案例ShowSquare:
            COUT<< 广场:<<值<< ENDL;
            打破;        默认:
            COUT<< 错误的计算方<< ENDL;
            打破;
    }
}


由于你正在编写一个C程序,默认调用机制是 CDECL 这意味着所有参数在栈上传递,返回值被传递回 EAX ,呼叫者负责事后清理堆栈。

所以为了叫PrintResult,你必须在调用存储过程之前,所有的参数压入栈。并且程序返回后,我们要清理我们栈( ADD ESP,8 )。

由于的cdecl 调用约定允许 EAX 来在通话过程中进行修改, EAX 时,可能无法PrintResult收益preserved,因此我们要将调用PrintResult之前计算的结果,然后后恢复调用返回。

我还没有试过上述code,但我希望它有助于让你去沿着正确的轨道上。


注意:由于您使用的是C ++编译器,的externC前,需要PrintResult

I need to call PrintResult from my assembly to display the result. I know I have to use extrn _PrintResult somewhere, and I should call the function using call _PrintResult but I'm not sure quite sure how to use it. any suggestions

public _Square

.386

.model flat

.code

_Square proc

mov eax, [esp+4]

imul eax

ret

_Square endp

.............Here is my C++ code.........

#include <iostream>

using namespace std;

enum ResultCode {ShowSquare};
enum SuccessCode {Failure, Success};

extern "C" long Square (long);

void main ()
 {
 long Num1; 
         long Num2;

 do
  {
  cout << "Enter Number to Square" << endl;
  cin >> Num1;
  Result = Square (Num1);
  cout << "Square is: " << Result << endl;
  } while (Result > 0);
 }

void PrintResult (ResultCode PrintCode, long Value) //PrintCode, long Value)
 {
 switch (PrintCode)
  {
  case ShowSquare:
    cout << "Display of square is: " << Value << endl;
    break;

  default:
    cout << "Error in assembly routines" << endl;
  }
}

解决方案

I usually don't like to post full code for things, but give this a try:

32-bit Assembly

.386
.model flat
.code

_Square proc
mov eax, [esp+4]
imul eax

push eax ; Save the calculated result

; Call PrintResult here
push eax ; value
push 0 ; ShowSquare
call _PrintResult
add esp, 8 ; Clear the stack

pop eax ; Return the calculated result

ret
_Square endp

C++

#include <iostream>

using namespace std;

enum ResultCode {ShowSquare};
enum SuccessCode {Failure, Success};

extern "C" long Square(long);

int main(int argc, char* argv[])
{
    long Num1, Num2;

    do
    {
        cout << "Enter number to square" << endl;
        cin >> Num1;
        Num2 = Square(Num1);
        cout << "Square returned: " << Num2 << endl;
    }
    while (Num2);

    return 0; 
}

extern "C"
void PrintResult(ResultCode result, long value)
{
    switch (result)
    {
        case ShowSquare:
            cout << "Square is: " << value << endl;
            break;

        default:
            cout << "Error calculating square" << endl;
            break;
    }
}


Because you are writing a C program, the default calling mechanism is cdecl which means that all the parameters are passed on the stack, the return value is passed back in eax, and the caller is responsible for cleaning up the stack afterward.

So in order to call PrintResult, you have to push all of your parameters onto the stack before invoking the procedure. And after the procedure returns, we have to clean up our stack (add esp, 8).

Because the cdecl calling convention allows eax to be modified during the call, eax may not be preserved when PrintResult returns, so we save the calculated result before calling PrintResult and then restore it after the call returns.

I have not tried the above code, but I hope it helps get you going down the right track.


Note: Because you are using a C++ compiler, the extern "C" before PrintResult is required.

这篇关于如何调用C ++函数在我的组装code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆