나는 하나의 스택 프레임에서 다른 스택 프레임으로 앞뒤로 건너 뛰는 "위험한"프로그램을 C++로 작성했다. 목표는 호출 스택의 가장 낮은 레벨에서 호출자로 건너 뛰고 무언가를 수행 한 다음 다시 호출하여 모든 호출을 건너 뜁니다.PIC 레지스터 (% ebx)의 기능은 무엇입니까?
스택 기본 주소 (%ebp
설정)를 수동으로 변경하고 레이블 주소로 점프하면됩니다. gcc와 icc 모두 함께 스택 손상없이 완전히 작동합니다. 이 일은 멋진 날이었습니다.
이제 동일한 프로그램을 가져와 C로 다시 작성하면 작동하지 않습니다. 특히 gcc v4.0.1 (Mac OS)에서는 작동하지 않습니다. 스택 기본 포인터가 올바르게 설정된 새 스택 프레임으로 이동하면 fprintf
을 호출하기 직전에 다음 명령이 실행됩니다. 여기에 나열된 마지막 명령은 역 참조 NULL, 충돌 :
lea 0x18b8(%ebx), %eax
mov (%eax), %eax
mov (%eax), %eax
좀 디버깅을 했어, 내가 알아 낸 것 그 내가 떠나기 전에 관찰 된 값을 사용하여 (스택 프레임을 전환 할 때 수동으로 %ebx
레지스터를 설정하여 처음에 함수), 버그를 수정합니다. 이 등록은 gcc에서 "위치 독립적 코드"를 다룬다는 것을 읽었습니다.
위치 독립적 코드 란 무엇입니까? 위치 독립적 코드는 어떻게 작동합니까? 이 레지스터 포인팅이란 무엇입니까?
setjmp/longjmp를 사용하여 % ebx를 직접 mucking하지 않고도이 기능을 사용할 수 있습니다. –
일반적으로 네, 맞습니다. 이 경우 호출자에게 점프하고 다른 기능을 실행 한 다음 호출 수신자에게 다시 호출 할 수 있어야합니다. setjmp/longjmp를 사용하면 다른 피 호출 함수가 겹쳐 쓸 수 있습니다. –