MSVC ++ 2013调试与发布编译问题

时间:2015-11-06 04:15:41

标签: c++ assembly visual-studio-2013 calling-convention

所以我正在尝试如何从ASM调用C ++程序。它适用于调试模式,但不是在发布模式上。

我的汇编代码如下所示:

sub rsp, 30h
mov rcx, 1
mov rdx, 2
mov r8, 3
mov r9, 4
mov qword ptr [rsp + 20h], 5
mov qword ptr [rsp + 28h], 6
call MyProc
add rsp, 30h
ret

MyProc功能如下所示:

extern "C"
{
    *other irrelevant methods here*

    void MyProc(int a, int b, int c, int d, int e, int f)
    {
        cout << "First & Last Param : " << a << " and " << f << endl;
    }
}

在调试模式下,它可以正常运行。在发布模式下,它失败并显示:Error 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF

什么事情发生了,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您可以在此处看到从ASM调用c ++函数的示例(正是您想要做的): how to use a library in masm or more specifcally a .lib file?

但我猜您的问题来自用于发布模式的优化。因为为库启用了优化时,必须调整汇编代码才能正常使用该优化库。

让我们看看你的情况。

以下是2个文件:

<强> lib.c

#include <iostream>

using namespace std;

extern "C"
{
    void MyProc(int a, int b, int c, int d, int e, int f)
    {
        cout << "First & Last Param : " << a << " and " << f << endl;
    }
}

<强> TEST.ASM

includelib source.lib
MyProc PROTO a:QWORD, b:QWORD, c:QWORD, d:QWORD, e:QWORD, f:QWORD

.CODE

    main PROC

    sub rsp, 30h
    mov rcx, 1
    mov rdx, 2
    mov r8, 3
    mov r9, 4
    mov qword ptr [rsp + 20h], 5
    mov qword ptr [rsp + 28h], 6
    call MyProc
    add rsp, 30h
    ret

    main ENDP

END

现在我尝试编译并链接两者。首先没有任何优化:

cl /c lib.c
lib lib.obj
ml64 test.asm /link /subsystem:console

在这种情况下代码将正确运行。但现在,如果您为库启用任何优化:

cl /c /O2 lib.c
lib lib.obj
ml64 test.asm /link /subsystem:console

您的代码将无法再正常运行。

答案 1 :(得分:0)

经过一些实验,我需要做的就是将堆栈指针除以大于或等于(函数* 8的参数个数)字节的任何数字,但数字必须以8结尾以保持堆栈对齐(归功于汉斯),所以数字如28h((<5 param),38h(6 - 7 param),48h(8 - 9 param)等都可以使用。

不确定我是否错了,但是堆栈的前4个字节是保留的,这就是为什么我需要将堆栈超过32个字节...