mir.pe (일반/밝은 화면)
최근 수정 시각 : 2024-11-03 17:39:41

엔디언



1. 개요2. 유래3. 특징4. 종류
4.1. Big Endian4.2. Little Endian4.3. Bi Endian
5. BOM과 엔디언6. 관련 문서

1. 개요

Endian

프로그래밍에서 메모리 등의 1차원 공간에서 데이터를 어떻게 배열하는지의 방식.

Endianness의 줄임말로, 엔디안이라고도 많이 부른다. 국제발음기호로 표기하면 /ɛn.di.ən/이므로 엔디언이 더 가깝다.

2. 유래

이건 조너선 스위프트의 작품인 《 걸리버 여행기》에서 유래한 단어다. 작중 릴리퍼트라는 난쟁이들이 사는 나라(소인국)에서 달걀을 먹을 때 "계란를 어느 쪽으로 깨먹는가?" 라는 논쟁으로 전쟁까지 벌이게 된 것에서 명칭이 유래되었다.

소설에서는 뭉툭한 끝을 깨먹은 사람들과 뾰족한 끝을 깨먹는 사람들이 자기들이 옳다며 논쟁을 벌이는데, 뭉툭한 끝을 깨먹는 사람들을 큰 끝(big end)을 깨먹는다고 ian을 붙여 big endian이라고 부르고, 반대의 경우를 작은 끝(little end)을 깨먹는다고 little endian이라고 부른다.

큰 끝을 깨든 작은 끝을 깨든 잘 먹기만 하면 상관없는 것을 쓸데없이 다투는 게, 마치 왼쪽부터 저장하든 오른쪽부터 저장하든 저장만 잘 되면 상관없는 메모리 저장 순서를 가지고 다투는 것과 비슷해 보여서 이런 이름이 붙었다고 한다. 단, 달걀 깨먹는 방향은 자기 입에만 잘 들어가면 그만이지만, 메모리 저장 순서는 프로그램 호환성 등에서 중요한 문제다.

3. 특징

데이터 교환에 있어 이 엔디언 취급이 매우 중요한 터라 x86bswap이나 AArch64/ARM의 rev등과 같이 메이저 프로세서들은 이 엔디언을 상호 변환하는 Instruction을 제공하고 있다. 컴파일러들 또한 엔디언간 변환을 빌트인 함수(내장 함수)로 제공하고 있어 타겟 프로세서에 맞는 코드를 생성해 주기도 한다.

이 문단에서 사용할 중요한 용어는 다음과 같다.
여기에서 significant는 '중요하다'는 뜻이 아니다. 'most significant' 자체가 숙어로, '최상위의', '맨 앞자리의'라는 뜻이다. 예를 들어 '12345'에서 most significant한 자리는 맨 앞의 '1'이다.

4. 종류

4.1. Big Endian

MSB가 가장 앞쪽에 오는 저장 방법. 예를 들어, 메모리에 0x12345678을 저장한다고 하면,
12 34 56 78
←작은 주소 큰 주소 →
이런 식으로 저장하는 것이다.

이때 표에서 한 칸은 1바이트를 의미한다. 보통 IBM이나 썬 마이크로시스템즈의 컴퓨터들이 이 방식을 채택한다. Java JVM은 호스트 운영체제나 하드웨어와 상관 없이 항상 Big Endian을 사용한다.

쉽게 말하면 주소를 오름차순으로 기록하는 방식이다.

사람이 보기에 직관적이라는 장점이 있다.

네트워크로 데이터를 주고받을 때에는 항상 Big Endian 형태로 다루도록 약속되어 있다.

4.2. Little Endian

LSB가 가장 앞쪽에 오는 저장 방법. 예를 들어, 메모리에 0x12345678을 저장한다고 하면,
78 56 34 12
←작은 주소 큰 주소 →
이런 식으로 저장하는 것이다.

리틀 엔디언이 언뜻 보기에는 비직관적으로 보이지만 8비트와의 하위호환성은 좋고, 데이터 캐스팅이 빠르다는 장점이 있다. 예를 들어 빅 엔디언에서는 32비트 변수를 16비트로 캐스팅하면 뒤의 두 바이트를 따로 복사해 와야 하지만 리틀 엔디언에서는 그냥 앞의 두 바이트만 읽어주면 된다.

쉽게 말하면 주소를 내림차순으로 기록하는 방식이다.

보통 인텔사의 칩셋과 호환이 되는 컴퓨터들이 이 방식을 채택한다. 그런데 그 인텔 시스템에 올라앉아 있는 자바 가상머신에서는 빅 엔디언을 사용한다.

4.3. Bi Endian

컴퓨터 시스템이, 또는 경우에 따라 사용자가 직접 데이터 저장 방식을 Big Endian과 Little Endian 중에서 고를 수 있는 형태. PowerPC에서는 부팅 시의 설정으로 빅 엔디언과 리틀 엔디언을 선택할 수 있다.

자신의 컴퓨터가 어느 저장 방법을 따르는지를 알고 싶으면 간단한 C 코드를 통해 이를 체크할 수 있다.[1]
#!syntax cpp
/*Endian_chk.c
*
*이진수 0000 0000 / 0000 0000 / 0000 0000 / 0000 0001(2)을 i에 저장한 후, 정수형 변수 i를 문자형 변수로 캐스팅한다.
*그렇게 하면 4바이트의 i는 1바이트의 길이 4인 배열이 된다.
*이제 이 배열의 시작 주소를 읽는다.
*이 값이 1이면 가장 마지막 자리가 가장 작은 주소에 저장되어 있다는 것(0000 0001(2))이므로 Little Endian이다.
*이 값이 0이면 가장 큰 자리가 가장 작은 주소에 저장되어 있다는 것(0100 0000(2))이므로 Big Endian이다.
*/

#include <stdio.h>

int main()
{
    int i = 0x00000001;
    if( ((char *)&i)[0] )
        printf( "Little Endian\n" );
    else
        printf( "Big Endian\n" );
} 


5. BOM과 엔디언

예를 들어 가(U+AC00)은 빅 엔디언에서는 AC 00으로 저장되고 리틀 엔디언에서는 00 AC로 저장된다. 그런데 이 AC 00이나 00 AC라는 바이트만으로는 프로그램이 엔디언을 판단할 수 없기에, 파일의 맨 앞에 이 문자를 삽입해서 프로그램이 엔디언을 판단할 수 있도록 도와준다. 즉 이 문자가 파일의 맨 앞에 삽입될 경우, 프로그램이 파일을 읽어들였을 때 첫 두 바이트가 FE FF이면 빅 엔디언, FF FE이면 리틀 엔디언임을 바로 판단할 수 있고, 파일을 올바르게 열 수 있다. 유니코드 인코딩 중 하나인 UTF-16을 .예시로 들면 아래와 같다.

이 문제 때문에 UTF-8은 아예 BOM에 의존적이지 않는 방식으로 설계했다.

6. 관련 문서



[1] 출처: http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Network_Programing/Documents/endian [2] not sign. 명제에서 부정을 나타내는 기호이다. 키보드로 입력할 수 없는 기호이기 때문에 보통 물결 기호(~) 혹은 느낌표(!)를 대신 사용한다.

파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는
문서의 r254
, 2.1번 문단
에서 가져왔습니다. 이전 역사 보러 가기
파일:CC-white.svg 이 문서의 내용 중 전체 또는 일부는 다른 문서에서 가져왔습니다.
[ 펼치기 · 접기 ]
문서의 r254 ( 이전 역사)
문서의 r66 ( 이전 역사)