0

我正在尝试在单独分配的堆栈上运行一个函数。

我想保留堆栈以供以后使用,以便我可以恢复它并恢复该功能。

以下代码编译并运行,但屏幕上没有任何内容。

#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

4

3 回答 3

2

欢迎使用 C++ 和名称修饰。C++ 中的函数名称被编译器修改(这样使用 gcc 函数对我来说变成了 _Z8functionv)。这是为了方便函数重载。编译器会跟踪它在后台赋予不同函数的实际名称,因此您不会意识到这一点。对于任何其他尝试与 C++ 交互的语言来说,这都是一个问题。

此代码不会链接到我的计算机上。

解决方案:1)用g++编译并传递-S标志(所以g++ -S test.cpp)。然后看一下汇编输出(cat test.s),看看调用了什么函数。然后将“调用函数”中的名称更改为“调用_Z8functionv”(对我来说 - 它对你来说很容易不同)。2)使用 C:将 cout << 更改为 printf 语句,以上应该可以工作。

我认为你没有使用 gcc(因为汇编器是从前到后的气体 - 我不得不切换汇编器上的所有操作数)。

于 2012-08-03T06:46:33.260 回答
1

根据 Intel 的 x86 文档MOV,第 3-403 页,您应该SS在加载新ESP值之前立即加载寄存器。这会阻止任何中断运行,直到ESP被分配。

于 2012-08-03T06:18:38.303 回答
1

实际上,我认为您的代码没有任何问题。您的样本按原样编译、链接并按预期运行。

也许您的控制台设置有问题,或者一些全局 STL/CRT 初始化或其他问题。无论如何,您可以在您的内部放置一个断点function以确保您到达那里。

于 2012-08-03T07:17:53.470 回答