Rumah >pembangunan bahagian belakang >C++ >Mengapakah Menggunakan Penunjuk Asas (%rbp) dalam C Inline Assembly Menyebabkan Segfaults?

Mengapakah Menggunakan Penunjuk Asas (%rbp) dalam C Inline Assembly Menyebabkan Segfaults?

Linda Hamilton
Linda Hamiltonasal
2025-01-01 07:57:14706semak imbas

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

Isu: Menggunakan Daftar Penunjuk Asas (%rbp) dalam Himpunan Sebaris C

Apabila menggunakan pemasangan sebaris untuk mengakses daftar penuding asas (%rbp) dalam C fungsi, kesalahan seg yang tidak dijangka berlaku selepas mengakses fungsi itu hujah.

Penjelasan

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.

Penyelesaian

Terdapat tiga penyelesaian utama untuk isu ini:

  1. Gunakan operan output "memori" (seperti tatasusunan calar) untuk ruang kerja dan jangan baca daripadanya.
  2. Langkau zon merah dengan menggunakan tambah $-128, %rsp / sub $-128, %rsp sekitar kod pemasangan.
  3. Kompilasi dengan -mno-red-zone (tetapi ambil perhatian bahawa ini bukan pilihan setiap fungsi).

Pendekatan Alternatif

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn