如何强制 GCC 使用 jmp 指令而不是 ret?
How to force GCC to use jmp instruction instead of ret?
我现在使用堆叠的协程进行网络编程。但是我受到了返回堆栈缓冲区失效的惩罚(请参阅 http://www.agner.org/optimize/microarchitecture.pdf 第 36 页),在上下文切换期间(因为我们手动更改了 SP 寄存器)
我发现jmp
指令比汇编语言测试后的ret
要好。但是,我还有一些函数可以间接调用用C++语言编写的上下文切换函数(由 GCC 编译)。我们如何在 GCC 汇编结果中使用jmp
而不是ret
强制这些函数返回?
一些常见但不完美的方法:
- 使用内联汇编并手动将 SP 寄存器设置为
__builtin_frame_address+2*sizeof(void*)
并jmp
到返回地址,然后再ret
?
这是一个不安全的解决方案。在C++中,局部变量或正确的值在ret
指令之前被破坏。如果我们jmp
,我们将省略这些说明。更糟糕的是,即使我们在 C 语言中,在ret
指令之前也需要恢复被调用方保存的寄存器,我们也会省略这些指令。
那么我们可以做些什么来强制GCC使用jmp而不是ret来避免上面列出的问题呢?
使用汇编程序宏:
.macro ret
pop %ecx
jmp *%ecx
.endm
将其放在文件顶部的内联汇编器或其他地方。
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- C++:对不存在的命名空间使用命名空间指令
- 函数名是c中该函数的第一条指令的地址吗
- 错误:无效的预处理指令 #i 的意思是 #if?
- 组装指令中乘法的下部和上部是什么
- OpenMP 与有序和关键指令并行
- C++中的移动分配出现问题.非法指令: 4.
- 嵌套命名空间的"using"指令,但需要命名内部命名空间
- 为什么 GCC 会发出重复的"ret"?
- C++CMake编译指令与
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- AVX 指令中寄存器和指针之间的客观差异
- while 循环 c++ 中的非法指令
- 为什么 ret 指令数大于调用指令数?
- 如何强制 GCC 使用 jmp 指令而不是 ret?
- 如何验证 LLVM "ret"指令是否返回 void?
- 使用"英特尔引脚"时跟踪不匹配的CALL和RET指令数
- 'ret'指令上的访问冲突