6

我正在尝试学习 ASM,并想尝试一些与 C++ 相结合的东西。ASM 部分是在一个裸函数中完成的。但是每当我调用函数(空)时,应用程序就会在下一个函数中崩溃。我应该在裸函数中做什么才能使其工作,我需要弹出 esp 什么的吗?一个例子可能会有所帮助。

_declspec(naked) void asmfunc()
{
    _asm
    {
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    i = 1;

    asmfunc();

    cout << i << endl; // <-- crash
    system("pause");

    return 0;
}
4

2 回答 2

15

裸函数将不包含任何编译器生成的序言和结尾代码。这也适用于函数末尾的隐式 return 语句。

这意味着您声明的函数ret最后没有指令。一旦控制权转移到asmfunc,它就永远不会返回。该函数继续执行该位置存在的任何代码,直到它遇到使其崩溃的东西。

基本上,您的原始实现asmfunc作为程序代码中间某处的标签工作。当你调用你的函数时,你实际上是在做一个goto asmfunc,即你将控制权转移到某个地方而没有任何返回的希望。

出于这个原因,一个最小的裸函数应该看起来像

_declspec(naked) void asmfunc()
{
    _asm
    {
      ret
    }
}

ret将指令放入裸函数是您的责任。

于 2012-07-08T18:09:46.357 回答
1

c 语言程序中的裸函数不包含准备函数来执行任务的序言和结尾代码。所以这是你制作序言和尾声代码的工作。在下面的代码中,你会看到我定义了序言和结尾,你可以在那里定义你的汇编代码。

__declspec(naked) void NakedFunction() {
    __asm {
        push ebp
        mov ebp, esp
    }

    __asm {
        // write your code here
    }

    __asm {
        leave
        ret
    }
}

int main() {
    NakedFunction();

    return 0x0;
}
于 2018-05-28T07:16:05.953 回答