切换 C++ 函数的调用堆栈
Posted
技术标签:
【中文标题】切换 C++ 函数的调用堆栈【英文标题】:Switching callstack for C++ functions 【发布时间】:2009-09-03 13:24:04 【问题描述】:这是我关于切换 C 调用堆栈的previous question。但是,C++ 使用不同的调用约定(thiscall)并且可能需要一些不同的 asm 代码。有人可以解释差异并指出或提供一些切换 C++ 调用堆栈的代码 sn-ps(最好在 GCC 内联 asm 中)吗?
谢谢, 詹姆斯
【问题讨论】:
是否有理由自己滚动而不是使用 setjmp / longjmp? 【参考方案1】:上一个问题中给出的代码应该可以正常工作。
thiscall calling convention 的区别仅在于谁负责将参数从堆栈中弹出。在 thiscall 调用约定下,被调用者弹出参数(另外,this
指针在 ecx
中传递);在 C 调用约定下,调用者弹出参数。这不会影响上下文切换。
但是,如果您要自己进行上下文切换,请注意,除了切换堆栈之外,您还需要保存和恢复寄存器(可能在堆栈上)。
请注意,顺便说一句,C++ 并不总是使用 thiscall ——它只用于具有固定数量参数的方法(除此之外,它是微软主义...... g++ 不使用它)。
【讨论】:
嗯,这个调用不只是关于隐藏的this
参数传递给被调用者的位置吗? (在某些寄存器中,IIRC;但我对此已经超出了我的理解范围,所以如果我在这里语无伦次地喋喋不休,请忽略我......)
您确定没有将 thiscall 与 fastcall 混淆吗?如果我没记错的话,thiscall 是通过 ecx 传递 this 指针的,而编译器有时确实使用 fastcall 来通过寄存器传递参数,而不是将它们推入堆栈。
是的,这听起来很对。我添加了指向 MSDN 条目的链接,其中包含详细信息。【参考方案2】:
注意 C++ 的 ABI 没有明确定义。
这个想法是编译器制造商能够针对这种情况使用最佳调用约定,从而使 C++ 更快。
这样做的缺点是每个编译器都有自己的调用约定,因此来自不同编译器的代码不兼容(即使来自同一编译器的不同版本(甚至不同优化标志)的代码也可能不兼容)。
【讨论】:
以上是关于切换 C++ 函数的调用堆栈的主要内容,如果未能解决你的问题,请参考以下文章