首頁 > 後端開發 > C++ > 為什麼在 C 內聯彙編中使用基底指標 (%rbp) 會導致段錯誤?

為什麼在 C 內聯彙編中使用基底指標 (%rbp) 會導致段錯誤?

Linda Hamilton
發布: 2025-01-01 07:57:14
原創
724 人瀏覽過

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
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板