2013-04-22 2 views
1

긴 단어 (예 : 필요합니다.) 뒤에 길이가 인 링커 명령 스크립트에 정의 된 링커 기호 (__BASE_ADDR이라고 함)가 있습니다. 주소가 0x0000000C이고 __BASE_ADDR이 0x00000010과 같은지 확인하십시오. 코드에서 __BASE_ADDR을 사용하고 0x0000000C에 액세스하기 위해 4를 뺍니다.C에서 링커 정의 기호에 액세스

링커 맵 출력 결과에서 __BASE_ADDR의 값이 0x00000010으로 올바르게 표시됩니다. 그러나 다음 C 코드를 사용하여 위치에 액세스하려고 시도하면 작동하지 않습니다.

extern unsigned char *__BASE_ADDR; 

void someFunc(void) 
{ 
    unsigned long Val = *((unsigned long *) (__BASE_ADDR - 4)); 

    /* Use Val for some comparison...*/ 
    /* ... */ 
} 

Val이 잘못된 값으로 설정됩니다. 무슨 일이 일어나고있는 지에는 __BASE_ADDR에있는 임의의 longword가 주소로 취해지고 4가 공제되고 결과 주소의 내용이 Val에 저장됩니다.

하지만 다음 작업을 수행 할 때, 그것은 잘 작동을 수행하고 발은 주소 0x0000000C에서있는대로 올바르게 설정됩니다

extern unsigned char __BASE_ADDR[]; 

void someFunc(void) 
{ 
    unsigned long Val = *((unsigned long *) (__BASE_ADDR - 4)); 

    /* Use Val for some comparison...*/ 
    /* ... */ 
} 

사람이 빛을 흘릴 수

? 나는 왜 당신이 링커 심볼의 내용에 접근 할 수 없는지 (기술적으로 내용이 없음) 이해하지만, 링커 심볼을 포인터로 액세스하고 그것을 배열로 액세스하는 것의 차이점은 무엇일까요?

감사합니다.

답변

1

(예 I 주소 0x0000000C에서 긴 단어 확인할 필요 __BASE_ADDR0x00000010 같다) 증상 0x00000010__BASE_ADDR 아니라고 말하지만 주소

.

그래서

unsigned long Val = *((unsigned long *) (__BASE_ADDR - 4)); 

실제로 0x00000010의 값 ( __BASE_ADDR의 값을 획득)를 판독 않고 그것에서 4를 뺀 val에 저장할 unsigned long의 어드레스와 결과를 해석한다.

unsigned long Val = *((unsigned long *) (__BASE_ADDR - 4)); 
  • 가 배열 이름 __BASE_ADDR 변환,이 경우 너무

    extern unsigned char __BASE_ADDR[]; 
    

    어레이 __BASEADDR의 주소

    는 어레이의 첫 번째 요소의 주소와 동일 첫 번째 요소에 대한 포인터 및 결과 주소가 __BASE_ADDR (다른 유형) 인 주소 인 0x00000010;

  • 그런 다음 unsigned char*에서 4를 뺀 결과 주소는 0x0000000C입니다.
  • 그 주소는 unsigned long*으로 변환되고 역 참조되며 여기에있는 값은 val에 저장됩니다.

는 (마지막 점은 매우 아마도 정의되지 않은 동작을 호출하지만 당신이 고정 된 주소를 다루는 경우는, 작동 알고 상황에있을 수 있습니다.) 내 나쁜

+0

, 즉 실제로 오타했다 - extern은 실제로 코드에서 char입니다. – tw39124

+0

현재 상황을 해결하기위한 답을 변경했습니다. –

+1

당신의 추측이 맞았습니다. 실제로 링커 심볼은 주소의 이름입니다. 따라서 링커 파일에 X = 5라고 쓰면 실제로 X는 주소 5의 이름입니다. C 코드에서 X에서 값 5를 추출하려면 X를 다음과 같이 선언해야합니다. 그러한 의미에 부합한다. – iheanyi