2010-03-19 8 views
4

8 비트 프로세서의 메모리에 int32 유형의 정수, 예를 들어 8051이있는 경우 해당 정수의 endianess를 어떻게 식별 할 수 있습니까? 컴파일러에 특정한가요? 시리얼 라인 등을 통해 멀티 바이트 데이터를 보낼 때 이것이 중요하다고 생각합니다.8 비트 프로세서가 엔디안 문제에 직면해야합니까?

+1

빅/리틀 엔디안을 사용하지 않아도되는 상황이 하나뿐이기 때문에 멀티 바이트 정수가 없습니다. 통신 채널이 8 비트 단위로 표준화되어있는 한 8 비트를 사용할 때만 안전합니다. 커뮤니케이션 채널이 다른 크기를 사용한다면 8 비트 단위로 엔디안에 대해 걱정해야합니다 (예 : 니블은 높고 낮은 것은 니블입니까?) 이것은 프로세서 유형과는 관련이 없습니다. – falstro

+0

지옥 같은 멀티 바이트 정수가 없더라도 채널 설계자는 전선에서 lsb-first 또는 msb-first를 지정해야하고 장치를 만드는 사람들은 그 점을 고려해야했습니다. ... – dmckee

+0

예, 정확히 저의 케이스. 와이어에서 멀티 바이트 데이터를 전송할 때 프로토콜과 메모리 레이아웃을 모두 알고 있어야합니다 ... – Grissiom

답변

7

더 넓은 정수를 기본적으로 지원하지 않는 8 비트 마이크로 컨트롤러를 사용하면 메모리에 저장된 정수의 엔디안은 실제로 컴파일러 작성자가 결정할 수 있습니다.

8051에서 널리 사용되는 SDCC 컴파일러는 정수를 리틀 엔디안 형식으로 저장합니다 (해당 컴파일러의 사용자 가이드는 데이터를 증가시키는 명령의 존재로 인해 해당 아키텍처에서 더 효율적이라고 주장합니다) 포인터가 아니라 감소를위한 포인터).

+3

또한 Keil C51 컴파일러는 정수를 빅 엔디안 형식으로 저장합니다. – mocj

+1

C51 컴파일러는 ** sbit ** 선언을 사용하여 액세스 한 객체가 리틀 엔디안 바이트 순서로 저장되어 있다고 가정합니다. ** sfr16 ** 유형의 경우입니다. 그러나 ** int ** 및 ** long **과 같은 표준 C 유형은 빅 엔디안에 저장됩니다. – jschmier

3

엔디안은 CPU 아키텍처에 따라 다릅니다. 컴파일러는 특정 CPU를 대상으로해야하기 때문에 컴파일러는 엔디안에 대한 지식도 갖게됩니다. 따라서 직렬 연결, 네트워크 등을 통해 데이터를 전송해야하는 경우 빌드 인 함수를 사용하여 네트워크 바이트 순서로 데이터를 넣을 수 있습니다. 특히 코드가 다중 아키텍처를 지원해야하는 경우 더욱 그렇습니다. 자세한 내용은

은 다음을 참조하십시오 http://www.gnu.org/s/libc/manual/html_node/Byte-Order.html

+0

Motorola 88000을 사용하지 않는 한 메모리의 데이터 엔디안이 명령어 인코딩에 정의되어 있지 않습니다 따라서 빅 엔디안과 리틀 엔디안은 자유롭게 상호 교환 될 수 있습니다. – Skizz

+0

예,하지만 더글러스가 지적했듯이 데이터를 어디서든 보내면 곧 엔디 언을 다루어야합니다. –

2

정수가에서 엔디안이 없습니다. 큰 또는 작은 엔디안 여부에 관계없이 바이트를 보는 것으로부터 판단 할 수 없습니다. 예를 들어, 8 비트 프로세서가 리틀 엔디안이고 빅 엔디안이라는 메시지를받는 경우 (예를 들어, 필드 버스 시스템이 빅 엔디안을 정의하기 때문에) 값을 변환해야합니다 8 비트 이상. 이를 하드 코딩하거나 바이트를 교환 할 시스템에 대한 정의가 필요합니다.

바이트 스와핑이 쉬운 점에 유의하십시오. 비트 필드의 비트 순서는 컴파일러마다 다르므로 비트 필드에서 비트를 스왑해야 할 수도 있습니다. 다시 말하지만 기본적으로 빌드 타임에이 사실을 알아야합니다.

0
#include <stdio.h> 

union foo { 
    int as_int; 
    char as_bytes[sizeof(int)]; 
}; 

int main() { 
    union foo data; 
    int i; 
    for (i = 0; i < sizeof(int); ++i) { 
     data.as_bytes[i] = 1 + i; 
    } 
    printf ("%0x\n", data.as_int); 
    return 0; 
} 

출력 해석은 귀하에게 달려 있습니다.

+0

또는 memcpy를 사용하면 구현에 대해 약간 약한 가정이 생깁니다. int intint; char asbytes [sizeof (int)]; <바이트 설정>; memcpy (& i, asbytes, sizeof (int));'. –

5

프로세서에 멀티 바이트 값을 사용하거나 멀티 바이트 레지스터가있는 작업이 있으면 엔디안 수준을 가질 수 있습니다.

http://69.41.174.64/forum/printable.phtml?id=14233&thread=14207은 8051이 다른 위치에서 다른 엔디안을 혼합한다는 것을 나타냅니다.

+0

감사! 나는 caf 's, SF와 당신의 대답을 함께 생각하게 될 것입니다. 귀하의 링크를 보내 주셔서 감사합니다;) – Grissiom

3

'51에는 컴파일러가 준수해야하는 것은 아닙니다. '51에는 컴파일러에서 준수해야하는 특정 엔디안의 고유 한 16 비트 레지스터 (DPTR, 표준에서 PC, ADC_IN, DAC_OUT 등)가 있지만 그 외에는 X는 1의 값을 다음 값 (1)는 최하위 바이트에있을 것입니다 할당 된 경우, 컴파일러는 ...

1
unsigned long int x = 1; 
unsigned char *px = (unsigned char *) &x; 

*px == 0 ? "big endian" : "little endian" 

당신은 프로젝트 구성에 선택하는 어떤이 선호 엔디안 또는 하나를 무료로 사용할 수 있습니다. 그런 다음 x를 바이트에 대한 포인터로 캐스트하면 포인터는 x의 가장 낮은 메모리 위치를 가리 킵니다. 메모리 위치가 0이면 빅 엔디안이고, 그렇지 않으면 리틀 엔디안입니다.

+0

그것은 단지 대답하는 방법이 아니라 테스트하는 것입니다. – Grissiom