mir.pe (일반/어두운 화면)
최근 수정 시각 : 2024-12-30 10:00:02

엔디언

엔디안에서 넘어옴


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 ( 이전 역사)