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