我正在尝试在单独分配的堆栈上运行一个函数。
我想稍后保留堆栈,以便我可以恢复它并恢复该功能。
以下代码编译并运行,但没有任何内容打印到屏幕上。
#include <cstdlib>
#include <csetjmp>
#include <iostream>
using namespace std;
unsigned char stack[65535];
unsigned char *base_ptr = stack + 65535 - 1;
unsigned char *old_stack;
unsigned char *old_base;
void function()
{
cout << "hello world" << endl;
}
int main()
{
__asm
{
mov old_base, ebp
mov old_stack, esp
mov ebp, base_ptr
mov esp, base_ptr
call function
mov ebp, old_base
mov esp, old_stack
}
}
使用vs2012 / win8 / intel Q9650
答案 0 :(得分:2)
欢迎使用C ++并命名mangling。 C ++中的函数名被编译器破坏(因此使用gcc函数对我来说变成了_Z8functionv)。这是为了方便功能重载。编译器会跟踪它在后台提供不同功能的实际名称,因此您不会意识到它。对于尝试与C ++交互的任何其他语言,这都是一个问题。
此代码不会在我的计算机上链接。
解决方案: 1)用g ++编译并传递-S标志(所以g ++ -S test.cpp)。然后看一下程序集输出(cat test.s)以查看函数的调用内容。然后将“调用函数”中的名称更改为“调用_Z8functionv”(对我来说 - 它可能很容易与您不同)。 2)使用C:改变cout&lt;&lt;对于printf语句,以上内容应该有效。
我认为你没有使用gcc(因为汇编程序回到了前面,因为我不得不切换汇编程序上的所有操作数)。
答案 1 :(得分:1)
根据英特尔针对MOV
的x86文档(第3-403页),您应该在加载新SS
值之前立即加载ESP
寄存器。这会阻止任何中断运行,直到ESP
被分配。
答案 2 :(得分:1)
实际上我没有看到您的代码有任何问题。 您的样本按原样进行编译,链接和运行。
也许您的控制台设置问题,或某些全局STL / CRT初始化或其他问题。无论如何,你可以在function
内放一个断点,以确保你到达那里。