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

MSVC++ 2013 Debug vs. Release Compiling Issue

所以我正在试验如何从 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

这是怎么回事,我该如何解决?

您可以在此处查看从 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

现在我尝试编译和 link 两者。首先没有任何优化:

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

您的代码将不再 运行 正确。

经过一些实验,我需要做的就是用大于或等于(函数的参数数量 * 8)字节的任意数字对堆栈指针进行子,但数字必须以 8 结尾保持堆栈对齐(归功于汉斯),因此像 28h for (< 5 param), 38h(6 - 7 param), 48h (8 - 9 param) 等数字会起作用。

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