2011-02-22 3 views
10

방금 ​​함수 포인터 (함수의 기계어 코드가 저장된 위치를 가리키는 포인터)에 대해 알게되었습니다. 이로 인해 기계 코드와 메모리에 저장되는 방법에 대해 생각하게되었습니다.함수 포인터 증분

기계 코드가 메모리에 연속적으로 저장되어 다음/이전 기능을 가리킬 때까지 포인터를 "수동으로"증가시킬 수 있습니까?

디버거의 기능은 무엇입니까? 그는 프로그램 카운터가 기계어 코드를 가리키는 곳을 "보게"할 수 있습니까?

결론 : 함수 포인터로 원시 디버거를 프로그래밍 할 수 있습니까?

나는이 권리를 이해 했는가, 아니면 벗어 났는가?

답변

3

종류 숫자 함수 이름, 변수 이름 라인의 어드레스를 디버깅 관한 정보를 이용하여

대부분 디버거 작업 (주로). 함수가 소스 코드에서와 같은 방식으로 메모리에 레이아웃되어 있다고 가정합니다. 대부분 컴파일러는 일반적으로 모든 빌려주는 주위를 움직입니다.

일 수 있습니다. 그러나 현재 명령에 대한 포인터가있는 코드를 단계별로 실행하고 해당 명령을 특정 양만큼 증가시켜 다음 명령을 얻습니다. 그러나이 경우 함수의 시작을 가리키는 것이 아니기 때문에 더 이상 함수 포인터이라고 부를 수 없습니다. 대신, 우리는 그것을 instruction pointer이라고 부를 것입니다.

는 사실,이 컴퓨터가 작동하는 방법을 정확하게 - 그것은 특별한 register는 항상 현재의 지시를 가리키는 program counter을 요구했다, 모든 명령 후 일정량을 증가 (A GOTO 명령은 쓰기에 해당 프로그램 카운터에 값). 내가 함수 포인터 이외는 C 메모리의 코드 세그먼트에 대한 포인터 포인트를 가질 수 있는지 모르겠어요, 사실 - 현실 세계에서

그러나,이 how debuggers work 아니다 . 다른 프로세서 유형의 에뮬레이터 작성과 같이 프로그램 카운터를 시뮬레이트해야하는 경우에만이 기술을 사용해야 할 것입니다.

2
  1. 기계 코드를 비 연속적으로 저장할 수 있습니다. 컴파일러는 자유롭게 일부 함수를 분할하거나 병합합니다 (최적화시)
  2. 포인터를 수동으로 증가 시키면 기능이 중간에 오게됩니다. 이는 잘못된 것입니다.
  3. 디버깅 루틴은 이미 사용할 수 있습니다. 현재 실행 지점의 스택 추적을 가져올 수 있으며 스택의 실행 포인터가 속한 함수 이름을 확인할 수 있습니다 (man backtrace, man backtrace_symbols). addr2line으로 줄 번호로 변환 할 수 있습니다.
1

개별 기능이 메모리에 어디에 저장되는지에 대한 보장은 없습니다.

함수 자체는 연속적인 메모리 블록이됩니다 (CPU가 순차적으로 명령을 실행하기 때문에). 그러나 코드 최적화를 활성화하면 함수 자체와 유사하지 않을 수 있습니다. 명령은 크게 재정리 될 수 있습니다. 다른 기능에서 정리 코드를 빌릴 수도 있습니다.

원시 디버거를 작성할 수는 있지만 함수가 끝나는 곳을 찾는 것은 쉽지 않습니다.

5

이렇게 할 수는 있지만 (적어도 일 수 있습니다. 일 수 있습니다.) 분명히 중요하지는 않습니다. 우선, 함수 포인터를 실제로 증가 시키거나 감소시킬 수는 없습니다. 주소를 가리키지 만 포인터 계산은 일반적으로 sizeof(pointed to type) 단위로 이루어 지지만 함수는 의미가 없기 때문에 ' 그것에 수학을하지 마십시오. 등

7

추적 할 수있는 초안 C 표준 (N1124)을 사용하면 유사한 규칙이 적용됩니다. 또한 식 (§ 6.5.6/2)의 부분은 두 피연산자 산술 형태를 가진다, 또는 하나의 피연산자는 개체 유형

에 포인터한다 첨가 용

어느 말한다 및 개체 유형

객체에 저장하거나 액세스하는 데 사용되는 식의 종류에 의해 결정되는 함수에 의해 리턴 된 값의 의미 § 6.2.5/1에 정의되어있다. 유형은 객체 유형 (객체를 완전히 설명하는 유형), 함수 유형 (함수를 설명하는 유형)으로 분할됩니다. , 불완전 유형 (객체를 설명하지만 크기를 결정하는 데 필요한 정보가없는 유형)이 있습니다.

함수 유형이 객체 유형과 구별되기 때문에 함수 포인터에 대한 포인터 연산이 금지되어 있습니다.

C++에서이 작업은 잘못된 것입니다. 첨가 용

어느 피연산자가 모두 산술 열거 타입 을 가진다 또는 하나의 피연산자가 완전히 정의 오브젝트 유형에 대한 포인터한다 § 5.7/1에 지정된 포인터 첨가의 정의는 다음을 말한다이고 다른 하나는 정수형 또는 열거 형이어야합니다. 그러나

, 오브젝트 타입 (아마도 CV 수식)이다

것을 § 3.9/구 상태 즉 함수 타입 아니라 참조 타입, 그리고 공극 아니다 입력 유형.

함께 사용하면 C++에서 함수 포인터를 증가시킬 수 없다는 것을 의미합니다.

희망이 도움이됩니다.

+0

나는이 대답이 요점을 놓치고 있다고 생각한다 - 이것은 개념 질문이었고 * "C에서 함수 포인터를 늘릴 수 있습니까?"그는 단지 * function-pointer *라는 용어를 오용하여 코드 세그먼트를 가리키는 포인터를 참조합니다. –

+0

@BlueRaja : 질문의 제목은 정확하게 그 것이고, 나는 해결할 가치가 있다고 생각합니다. –