2013-06-25 2 views
1
// Register: BAUDCTL 
    extern volatile unsigned char   BAUDCTL    @ 0x09B; 
    #ifndef _LIB_BUILD 
asm("BAUDCTL equ 09Bh"); 
    #endif 

@ 기호는 무엇입니까? 주소 0x09B에서 캐시 할 수없는 부호없는 char을 정의한다는 의미입니까? 그러면 어셈블리에서 asm 함수가 필요한 이유는 무엇입니까?C에서 다음을 정의합니다.

답변

5

컴파일러 확장자 ​​이고 표준 C의 일부가 아닙니다. 변수를 주소 0x09b에 배치합니다. 임베디드 플랫폼 용 컴파일러의 작은 하위 집합에만 사용되며 하드웨어 레지스터에 대한 변수를 갖는 것이 일반적입니다.


이것에 대한 또 다른 일반적인 기술은 자신의 선언에 @을 (그들이 준수 더 기준은 즉)를 지원하지 않습니다 컴파일러에 포인터를 사용하는 것입니다. 그런 다음이의 단점은 전송 제어 레지스터는 현재 메모리에 두 곳, 포인터 변수의 실제 하드웨어 레지스터, 다른 하나를 차지한다는 것입니다

volatile unsigned char *BAUDCTL = (unsigned char *) 0x09b; 

과 같을 것입니다. 또 다른 단점은 레지스터에 액세스 할 때 포인터 역 참조 연산자를 사용해야한다는 것입니다.

+1

나는 마이크로 칩이 이것을 링커에 맡겨두고 시작했다고 생각한다. 나는 그것을 완전히 이해하지는 못했지만 헤더 파일과 일치하는 링커 스크립트를 작성한다고 생각하기 때문에 코드에서 이름을 사용하여 메모리 맵 레지스터로 취급 할 수 있지만 여전히 적절한 C를 작성한다. – detly

2

이것은 표준 C가 아니며 확장의 일부 형식이므로 구현에 따라 다릅니다. 그러나 나는 당신이 옳았다는 것이 아주 좋은 기회라고 말했을 것이고 그것은 기본적으로 그 캐릭터가 주소 0x9b에 있다고 말하고있다.

이것은 일반적으로 임베디드 시스템에서 메모리 매핑 I/O가 수행되는 방식입니다. asm 비트의 필요성에 관해서는

는, 다시는 (잘 교육이지만) 추측이다 : 당신 나중에 asm 블록 내에서 사용하려는 경우 extern는 음, C 코드 BAUDCTL을 정의 할 수 있지만, 또한 어셈블러 정의가 필요할 수도 있습니다. asm 블록 내의 C 정의를 쉽게 얻을 수있는 방법이 없을 수도 있습니다.

관련 문제