>백엔드 개발 >C++ >기본 포인터 레지스터(%rbp)를 사용하는 인라인 어셈블리가 C에서 세그먼트 오류를 ​​일으키는 이유는 무엇입니까?

기본 포인터 레지스터(%rbp)를 사용하는 인라인 어셈블리가 C에서 세그먼트 오류를 ​​일으키는 이유는 무엇입니까?

Patricia Arquette
Patricia Arquette원래의
2024-12-28 02:17:10597검색

Why Does My Inline Assembly Using the Base Pointer Register (%rbp) Cause a Seg Fault in C  ?

C 인라인 ASM에서 기본 포인터 레지스터 사용

질문:

시도 중입니다. 인라인 어셈블리 내에서 기본 포인터 레지스터(%rbp)를 사용합니다. 그러나 인라인 asm 이후에 변수에 액세스하면 프로그램 세그먼트 오류가 발생합니다. 아래 코드 조각은 문제를 보여줍니다.

void Foo(int &x) {
    asm volatile ("pushq %%rbp;"
                  "movq %%rsp, %%rbp;"
                  "subq , %%rsp;"
                  "movl , -12(%%rbp);"
                  "movq %%rbp, %%rsp;"
                  "popq %%rbp;"
                  : : : );
    x = 5;
}

문제 진단:

코드 세그먼트 오류는 RSP 아래의 "빨간색 영역"에 저장된 값을 덮어쓰기 때문에 발생합니다. , GCC가 저장하는 데 사용하는 것 value.

해결책:

이 문제를 방지하려면 "=m" 출력 피연산자를 사용하여 인라인 asm에 스크래치 공간을 할당하거나 다음을 사용하여 빨간색 영역을 명시적으로 건너뜁니다. 하위 $-128, %rsp 명령어. 또는 처음부터 스크래치 공간을 사용하지 말고 컴파일러가 레지스터를 할당하고 저장하도록 하십시오.

인라인 ASM 모범 사례:

  • 인라인 유지 ASM은 최대한 간결하며 이상적으로는 컴파일러가 생성할 수 없는 명령어만 포함합니다.
  • 입력/출력 제약 조건을 사용하세요. ASM과 C 코드 간의 데이터 흐름을 지정합니다.
  • 큰 코드 블록에는 인라인 ASM을 사용하지 마세요. 대신 어셈블리 함수 작성을 고려해 보세요.

추가 팁:

  • 인라인 ASM을 사용할 때 스택 아래의 "빨간색 영역" 영역에 유의하세요. 포인터.
  • 입력 제약 조건을 사용하여 입력용 레지스터를 지정할 수 있으므로 명시적 레지스터의 필요성이 줄어듭니다. 할당.
  • 코드가 플래그를 수정하는 경우 "cc"(조건 코드) 클로버를 선언하세요.

위 내용은 기본 포인터 레지스터(%rbp)를 사용하는 인라인 어셈블리가 C에서 세그먼트 오류를 ​​일으키는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.