> 백엔드 개발 > C++ > C 인라인 어셈블리에서 기본 포인터(%rbp)를 사용하면 Segfault가 발생하는 이유는 무엇입니까?

C 인라인 어셈블리에서 기본 포인터(%rbp)를 사용하면 Segfault가 발생하는 이유는 무엇입니까?

Linda Hamilton
풀어 주다: 2025-01-01 07:57:14
원래의
693명이 탐색했습니다.

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

문제: C 인라인 어셈블리에서 기본 포인터 레지스터(%rbp) 사용

인라인 어셈블리를 사용하여 C에서 기본 포인터 레지스터(%rbp)에 액세스하는 경우 기능에 액세스한 후 예기치 않은 세그먼트 오류가 발생합니다. 인수.

설명

문제는 GCC가 추적해야 하는 값을 저장하는 RSP(또는 빼기 포인터) 아래의 "빨간색 영역"을 밟는 데 있습니다. 제공된 예제 코드에서는 인라인 어셈블리 내에서 푸시 명령이 사용되어 %rsp를 8만큼 감소시키고 함수 인수(&x)의 하위 32비트를 덮어씁니다.

인라인 어셈블리가 완료되면 GCC 클로버링된 값을 4바이트 저장소의 주소로 사용하려고 시도하여 세그먼트가 발생합니다. 결함.

해결책

이 문제에 대한 세 가지 주요 해결 방법은 다음과 같습니다.

  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)를 사용하면 Segfault가 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿