Little-Endian 은 도대체 어떻게 정렬되었나요?
Big-Endian 및 Little-Endian 바이트 정렬
바이트 정렬 의미
Big-Endian 한 Word 에서 높은 Byte 는 메모리의 이 Word 영역의 낮은 주소에 배치됩니다.
Little-Endian 한 Word 에서 낮은 Byte 는 메모리의 이 Word 영역의 낮은 주소에 있습니다. < P > 테이블에서 Word 의 길이는 16 비트이고 Byte 의 길이는 8 비트라는 점에 유의해야 합니다. 숫자가 두 개 이상의 Word 길이를 초과하는 경우 먼저 Word 별로 여러 부분으로 나눈 다음 각 부분 (즉, 각 Word 내부) 이 Big-Endian 또는 Little-Endian 의 다른 작업으로 바이트를 처리해야 합니다.
예:
x 으로 시작하는 메모리에 x1234abcd 를 쓰면 , 그 결과
big-endian little-endian
xx12 x CD
x1 x34 xab
x2xab 가 산출됩니다 x34
x3 xcd x12
(참고: xab 를 2 진수로 변환하는 것은 11111 이며 8bit 의 수입니다. )
는 다음과 같이 자세히 설명합니다.
시스템마다 CPU 의 메모리 내 데이터 저장소에는 차이가 있는 경우가 많습니다. 예를 들어, Intel 의 x86 시리즈 프로세서는 시작 주소에 낮은 순서 바이트를 저장하고, IBM 의 37 호스트가 사용하는 PowerPC 나 Motorola 가 생산하는 CPU 와 같은 일부 RISC 아키텍처 프로세서는 시작 위치에 높은 순서 바이트를 저장합니다. 이 두 가지 서로 다른 저장 방법을 little-endian 과 big-endian 이라고 합니다.
little-endian 은 x86 시리즈 CPU 의 데이터 저장 방식이며 낮은 순서의 부분을 앞에 저장합니다. Big-endian 은 높은 순서 부분을 앞에 저장하는 것입니다. 예를 들어 xF432 를 저장하기 위해 little-endian 은 32F4 로 저장되고 big-endian 을 사용하는 대신 그림 13.2 와 같이 F432 로 저장됩니다. < P > 프로그램 p13.1.c 는 시스템이 big-endian 또는 little-endian 을 사용하여 데이터 스토리지를 구현했는지 여부를 판단하는 방법을 설명합니다. 프로그램에서 사용되는 방법은 다음과 같습니다.
그림 13.2 big-endian 및 little-endian 방식 데이터 저장소 예
(1) 통합 기능 활용 통합 내의 데이터 멤버는 * * * 공유 스토리지 공간이며, 할당된 공간은 데이터 멤버에서 필요한 최대 메모리 수입니다. 프로그램은 두 개의 데이터 멤버, 즉 short 유형의 데이터 멤버 (32 비트 시스템의 경우 short 유형의 길이는 2 바이트), 문자 유형의 문자 배열, 문자 배열의 요소 수가 short 유형의 바이트 수인 endian_un 이라는 컨소시엄을 정의합니다.
프로그램은 var 에 x12 값을 할당합니다. 연합구조의 특징으로 인해 bits 문자열 배열에도 x12 라는 숫자가 저장됩니다. 문자열의 저위와 고위에 저장된 내용을 판단함으로써 시스템이 little-endian 인지 big-endian 인지 알 수 있다.
(2) 강제 유형 변환을 통해 구현됩니다. 프로그램에서 flag 변수의 주소를 취하여 시작 공간의 저장 내용을 얻습니다. 시작 공간에 데이터의 낮은 내용이 저장되어 있으면 little-endian 으로 저장하고, 그렇지 않으면 big-endian 으로 저장합니다.
프로그램의 구체적인 코드는 다음과 같습니다.
//p13.1.c 판단 big-endian 및 little-endian#include < Stdio.h> //유형 강제 변환을 사용하여 little-endian 과 big-endian 의 판단 int is _ little _ endian (void) {unsigned shortflag = x4321; If(*(unsigned char*)& Flag==x21)return 1; Elsereturn ; }int main(void){// little-endian 및 big-endian union endian _ un {shortvar; 를 결정하기 위해 통합 기능을 사용합니다. Char bits[sizeof(short)]; } Union endian_un flag; Flag.var=x12; //낮은 및 높은 저장 내용을 판단하고 if (sizeof (short) = = 2) {if (flag.bits [] = = 1 & & Flag.bits [1] = = 2) printf ("judged by first method, big-endian/n"); Else if(flag.bits[]==2 & & Flag.bits [1] = = 1) printf ("judged by first method, little-endian/n"); Elseprintf ("cannot determine the type/n"); } if (is _ little _ endian ()) printf ("judged by second method, little-endian/n"); Elseprintf ("judged by second method, big-endian/n"); Return ; }
gcc 를 사용하여 p13.1.c 를 컴파일하고 p13.1 이라는 실행 파일을 얻습니다. 이 절차를 실행하는데 구체적인 출력은 다음과 같다. X86 시스템의 메모리 데이터가 little-endian 방식으로 저장되는 것을 볼 수 있습니다.
[program @ localhostcharter13] $ gcc-o p13.1p13.1.c [program @ localhostcharter13] $./p11p Little-endian judged by second method, little-endian [program @ localhostcharter 13] $
big-endian 을 소개하는 이유 호환성 문제를 피하기 위해 네트워크의 데이터 전송은 모두 높은 순서에서 낮은 순서로 저장됩니다. 따라서 낮은 바이트 우선 순위 (little-endian) 시스템에서 네트워크로 데이터를 전송하려면 먼저 변환해야 합니다. Big-endian 의 기계는 변환할 필요가 없습니다.
Linux 시스템은 바이트 순서 변환을 위해 htons, htonl, ntohs, ntoh 의 네 가지 함수를 제공합니다. 여기서 h 는 host 의 약어이고 n 은 network 입니다. 마지막 문자인 s 는 short 유형을 나타내고 l 은 long 유형을 나타냅니다. 4 개의 함수는 다음과 같이 구체적으로 정의됩니다.
uint32 _ thtonl (uint32 _ thostlong);
uint16 _ thtons (uint16 _ thostshort);
uint32 _ t ntohl (uint32 _ t netlong);
uint16 _ t ntohs (uint16 _ t netshort);
htonl/htons: 호스트 바이트 순서가 네트워크 바이트 순서로 변환되었음을 나타냅니다. htonl 함수와 htons 함수의 차이는 매개변수 길이가 다르다는 것입니다.
ntohl/ntohs: 네트워크 바이트 순서가 호스트 바이트 순서로 변환되었음을 나타냅니다. ntohl 함수와 ntohs 함수의 차이는 매개변수 길이가 다르다는 것입니다.