인라인 어셈블리를 사용하여 C에서 기본 포인터 레지스터(%rbp)에 액세스하는 경우 기능에 액세스한 후 예기치 않은 세그먼트 오류가 발생합니다. 인수.
문제는 GCC가 추적해야 하는 값을 저장하는 RSP(또는 빼기 포인터) 아래의 "빨간색 영역"을 밟는 데 있습니다. 제공된 예제 코드에서는 인라인 어셈블리 내에서 푸시 명령이 사용되어 %rsp를 8만큼 감소시키고 함수 인수(&x)의 하위 32비트를 덮어씁니다.
인라인 어셈블리가 완료되면 GCC 클로버링된 값을 4바이트 저장소의 주소로 사용하려고 시도하여 세그먼트가 발생합니다. 결함.
이 문제에 대한 세 가지 주요 해결 방법은 다음과 같습니다.
위험 영역 오버런을 사용하는 대신 "=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 중국어 웹사이트의 기타 관련 기사를 참조하세요!