當使用內聯彙編存取 C 中的基底指標暫存器 (%rbp)時函數,存取函數後發生意外的段錯誤
問題在於踩到RSP(或減法指針)下方的“紅色區域”,該區域存儲GCC需要跟踪的值。在提供的範例程式碼中,在內聯彙編中使用了推送指令,該指令將 %rsp 遞減 8 並覆寫函數參數的低 32 位元 (&x)。
當內聯彙編完成時,GCC嘗試使用破壞的值作為4 位元組儲存的位址,導致seg
此問題主要有以下三種解:
不要使用紅色區域溢出,而是考慮使用「=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中文網其他相關文章!