Apabila menggunakan pemasangan sebaris untuk mengakses daftar penuding asas (%rbp) dalam C fungsi, kesalahan seg yang tidak dijangka berlaku selepas mengakses fungsi itu hujah.
Masalahnya terletak pada memijak "zon merah" di bawah RSP (atau tolak penunjuk), yang menyimpan nilai yang perlu dijejaki GCC. Dalam contoh kod yang disediakan, arahan tolak digunakan dalam himpunan sebaris, yang mengurangkan %rsp sebanyak 8 dan menimpa 32 bit bawah hujah fungsi (&x).
Apabila pemasangan sebaris selesai, GCC cuba menggunakan nilai terkumpul sebagai alamat untuk stor 4-bait, yang membawa kepada seg kesalahan.
Terdapat tiga penyelesaian utama untuk isu ini:
Daripada menggunakan overrun zon merah, pertimbangkan untuk memperuntukkan ruang kerja secara eksplisit dalam pemasangan sebaris menggunakan kekangan "=m", sebagai dilihat dalam contoh kod diperbetulkan berikut:
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; }
Di sini, kekangan "=m" memastikan ruang kerja diperuntukkan dalam zon merah dan mengelak daripada menulis ganti argumen fungsi.
Atas ialah kandungan terperinci Mengapakah Menggunakan Penunjuk Asas (%rbp) dalam C Inline Assembly Menyebabkan Segfaults?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!