2012-10-05 2 views
1

바이트 배열에서 단어를 읽는 데 혼란이 있습니다. 배경 컨텍스트는 C 언어로 작성된 MIPS 시뮬레이터에서 인트로 컴퓨터 아키텍처 클래스로 작업하고 있지만 코드를 디버깅하는 동안 C 프로그래밍 관점에서 이해할 수없는 놀라운 결과를 얻었습니다. 내가 수동으로 mipsaddr라는 주소에 메모리 블록의 네 가지로 uint32_t 값을 저장 내 일부 테스트하는 동안C 프로그래밍 : 바이트 배열의 단어

uint8_t *mem; 
//... 
mem = calloc(MEM_SIZE, sizeof(uint8_t)); // MEM_SIZE is pre defined as 1024x1024 

(A)에서 한 바이트 :

나는 다음과 같이 MEM라는 바이트 배열이 정의되어 시간으로는 다음과 같습니다

for(int i = 3; i >=0; i--) { 
     *(mem+mipsaddr+i) = value; 
     value = value >> 8; 
     // in my test, value = 0x1084 
} 

을 마지막으로, 나는이 두 가지 방법 중 하나를 배열에서 단어를 읽으려고 테스트했다. , I 수동으로 각각의 셀에서 각 바이트를 읽어 번째 방법

uint32_t foo = *(uint32_t*)(mem+mipsaddr); 
printf("foo = 0x%08x\n", foo); 

다음 비트 시프트와 함께 추가 : 첫 번째 방법에서, I은 기본적으로 한번에 변수로 전체 단어 읽기를 시도

uint8_t test0 = mem[mipsaddr]; 
    uint8_t test1 = mem[mipsaddr+1]; 
    uint8_t test2 = mem[mipsaddr+2]; 
    uint8_t test3 = mem[mipsaddr+3]; 

    uint32_t test4 = (mem[mipsaddr]<<24) + (mem[mipsaddr+1]<<16) + 
       (mem[mipsaddr+2]<<8) + mem[mipsaddr+3]; 
    printf("test4= 0x%08x\n", test4); 

코드의 출력은 이상이 같이 나왔다 : foo는 = 0x84100000 TEST4 = 0x00001084

TEST4의 값은 내가이 될 것으로 기대 정확히이지만, foo는이 순서를 반대로 것으로 보인다 바이트 수 왜 이것이 사실입니까? foo의 경우, uint32_t * 포인터가 mem [mipsaddr]을 가리킬 것으로 예상하고, 32 비트 길이이기 때문에 어레이에 존재하는 순서대로 모든 32 비트를 읽습니다 (00001084) . 분명히, 내 이해가 정확하지 않습니다.

저는 여기에 초보자이며이 질문에 대한 답변을 검색했지만 찾지 못했습니다. 이미 게시 된 경우 사과드립니다. 그러나 그렇지 않다면, 나는 누군가가 나를 여기에서 계몽 할 수 있기를 바랍니다.

+0

그냥 명확하게하기에 (uint8_t *)를 주조에서 오는, mipsaddr는 [1, MEM_SIZE) 내에 정의 여기에. – UberJason

+0

endianness의 문제 인 것 같습니다 –

+0

첫 번째 코드에서 value = value >> 8 * i; 이것이 도움이되는지 알려주십시오. – mihirj

답변

5

그것은 (무엇보다도) 여기 설명 : http://en.wikipedia.org/wiki/Endianness

메모리에 하나의 바이트보다 큰 데이터를 저장,이 아키텍처 (수단은 CPU) 된 바이트가 저장되는 순서에 의존한다. 가장 중요한 바이트가 먼저 저장되고 최하위 바이트가 마지막으로 저장되거나 그 반대로 저장됩니다. 바이트 액세스 조작을 통해 개별 바이트를 다시 읽은 다음 다시 병합하여 원래 값을 다시 작성하면 특정 시스템의 endian을 고려해야합니다.

For 루프에서 가장 중요한 바이트부터 시작하여 바이트 단위로 값을 저장합니다 (인덱스를 세는 것은 약간 잘못된 것입니다 ;-). 그러면 추억은 다음과 같이 보입니다. 0x00 0x00 0x10 0x84.

다음은 32 비트 (4 바이트) 단일 액세스로 단어를 읽는 중입니다. 아키텍처에 따라 0x00001084 (빅 엔디안) 또는 0x84100000 (리틀 엔디안)이됩니다. 후자를 얻었으므로, 당신은 리틀 엔디안 시스템으로 작업하고 있습니다.

두 번째 접근법에서는 개별 바이트를 저장 한 순서와 동일한 순서로 (가장 중요하게 먼저) 사용자가 이전에 저장 한 것과 동일한 값을 다시 얻습니다.내가 포기하지 않았더라도

0

그것은 어쩌면, 엔디안 문제가 될 것으로 보인다 (uint32_t *)

관련 문제