我现在在使用堆栈式协程序进行网络编程。但是我受到返回堆栈缓冲区无效的惩罚(请参阅
http://www.agner.org/optimize/microarchitecture.pdf第36页),在上下文切换期间(因为我们手动更改了SP寄存器)
经过汇编语言测试后,我发现jmp
指令比ret
更好。但是,我还有其他一些函数可以间接调用用C++语言(由GCC编译)编写的上下文切换函数。我们如何在GCC汇编结果中使用jmp
而不是ret
强制这些函数返回?
一些常见但不完善的方法:
使用内联汇编的
__builtin_frame_address+2*sizeof(void*)
之前手动将SP寄存器设置为jmp
并将ret
设置为返回地址? 这是不安全的解决方案。在C++中,局部变量或右值在
ret
指令之前被销毁。如果我们使用jmp
,我们将省略这些指令。更糟糕的是,即使我们在C语言中,也需要在ret
指令之前恢复被调用方保存的寄存器,并且我们也将省略这些指令。那么,我们可以怎么做来强制GCC使用jmp而不是ret来避免在上面列出的问题?
最佳答案
使用汇编宏:
.macro ret
pop %ecx
jmp *%ecx
.endm
将该内联汇编程序放在文件顶部或其他位置。