如何强制 GCC 使用 jmp 指令而不是 ret?

How to force GCC to use jmp instruction instead of ret?

本文关键字:ret 指令 何强制 GCC 使用 jmp      更新时间:2023-10-16

我现在使用堆叠的协程进行网络编程。但是我受到了返回堆栈缓冲区失效的惩罚(请参阅 http://www.agner.org/optimize/microarchitecture.pdf 第 36 页),在上下文切换期间(因为我们手动更改了 SP 寄存器)

我发现jmp指令比汇编语言测试后的ret要好。但是,我还有一些函数可以间接调用用C++语言编写的上下文切换函数(由 GCC 编译)。我们如何在 GCC 汇编结果中使用jmp而不是ret强制这些函数返回?

一些常见但不完美的方法:

  1. 使用内联汇编并手动将 SP 寄存器设置为__builtin_frame_address+2*sizeof(void*)jmp到返回地址,然后再ret

这是一个不安全的解决方案。在C++中,局部变量或正确的值在ret指令之前被破坏。如果我们jmp,我们将省略这些说明。更糟糕的是,即使我们在 C 语言中,在ret指令之前也需要恢复被调用方保存的寄存器,我们也会省略这些指令。

那么我们可以做些什么来强制GCC使用jmp而不是ret来避免上面列出的问题呢?

使用汇编程序宏:

.macro ret
pop %ecx
jmp *%ecx
.endm

将其放在文件顶部的内联汇编器或其他地方。