首页 > 后端开发 > C++ > 为什么在 C 内联汇编中使用基指针 (%rbp) 会导致段错误?

为什么在 C 内联汇编中使用基指针 (%rbp) 会导致段错误?

Linda Hamilton
发布: 2025-01-01 07:57:14
原创
701 人浏览过

Why Does Using the Base Pointer (%rbp) in C   Inline Assembly Cause Segfaults?

问题:在 C 内联汇编中使用基指针寄存器 (%rbp)

当使用内联汇编访问 C 中的基指针寄存器 (%rbp) 时函数,访问该函数后发生意外的段错误

说明

问题在于踩到RSP(或减法指针)下方的“红色区域”,该区域存储GCC需要跟踪的值。在提供的示例代码中,在内联汇编中使用了推送指令,该指令将 %rsp 递减 8 并覆盖函数参数的低 32 位 (&x)。

当内联汇编完成时,GCC尝试使用破坏的值作为 4 字节存储的地址,导致 seg

解决方案

此问题主要有以下三种解决方案:

  1. 为工作区和内存使用“内存”输出操作数(例如临时数组)不要从中读取。
  2. 使用 add $-128, %rsp / sub 跳过红色区域$-128, %rsp 围绕汇编代码。
  3. 使用 -mno-red-zone 进行编译(但请注意,这不是每个函数的选项)。

替代方法

不要使用红色区域溢出,而是考虑使用“=m”约束在内联程序集中显式分配工作空间,如以下是更正后的代码示例:

void Bar(int &x)
{
    int tmp;
    long tmplong;
    asm ("lea  -16 + %[mem1], %%rbp\n\t"
         "imul , %%rbp, %q[reg1]\n\t"  // q modifier: 64bit name.
         "add  %k[reg1], %k[reg1]\n\t"    // k modifier: 32bit name
         "movl , %[mem1]\n\t" // some asm instruction writing to mem
           : [mem1] "=m" (tmp), [reg1] "=r" (tmplong)
           :
           : "%rbp"
         );
    x = 5;
}
登录后复制

这里,“=m”约束确保工作空间分配在红色区域内,并避免覆盖函数参数。

以上是为什么在 C 内联汇编中使用基指针 (%rbp) 会导致段错误?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板