같은 일을 하는데 방법이 두가지가 있다면, 아마도 두개의 서로다른 회사는 서로다른 방법을 채용할 가능성이 다분할 것입니다. 머피의 법칙이기도 한 이런 가능성은 서로다른 칩디자이너가 메모리에서 데이타를 서열화하는 방법에도 또한 마찬가지로 통용됩니다.
동화(Fable)
걸리버 여행기에 등장하는 소인국(lilliputian)은 매우 작은 나라인데, 그에 걸맞게 사소한 정치적인 문제를 가지고 있었습니다. Big-Endian당과 Little-Endian당이 격론을 벌이는데, 그 격론의 내용이라는 것이 반숙된 달걀을 깨고자 할때, 뭉툭한 끝(Big-End)을 먼저 깰것인가 아니면 뾰족한 끝(Litttle-End)부터 먼저 깰것인가라는 것이 었습니다. (-_-;;)
1980년 4월 1일, 대니 코헨(Danny Cohen)이 지금에서는 유명하게 된 "On Holy Wars and a Plea for Peace"라는 책에서 워드에서의 바이트 오더링(Byte Ordering in Words)에 대해 논하면서 '엔디안'이라는 용어를 이 문제를 지칭하는데 처음 사용했습니다. 그 후 곧바로 이 용어는 고착되었고,엔디안이라는 용어는 단지 바이트 오더링만을 의미하게 되었습니다.(1)
(1) "Byte Sex"라는 용어가 사용되기도 합니다. 유닉스 프로그래머는 "NUXI 문제"라고 부르기도 하는데, 바이트 오더링에 착오가 생기면 'UNXI"라는 단어의 입력에 대해 앞뒤가 뒤바뀌어 'NUXI'라는 출력이 나오니까 말입니다.
[이진 엔디안(Binary Endian)]
컴퓨터 메모리는 기나긴 비트(0과 1의 상태를 스위칭하는)의 배열입니다. 이러한 비트들의 조각이 모여 바이트(여덟개의 비트), 그리고 워드(16bits),롱워드(32bits),쿼드워드(64bits)로 단위 그룹화됩니다.
MSB,LSB
12라는 십진수를 이진숫자로 변환한다고 생각해보십시오. 너무나 당연하게도 '1100'이라는 이진수를 떠올린다면,아마도 당신은 걸리버 여행기에서 달걀은 뭉툭한 끝을 깨어서 먹어야한다고 주장하는 빅엔디안족에 분류가 될것입니다. 글자를 쓸경우 왼쪽에서 오른쪽으로 쓰는 나라도 있고, 오른쪽에서 왼쪽으로 쓰는 나라, 그리고 위에서 밑으로 내려쓰는 나라도 있습니다. 아쉽게도 밑에서 위로 쓰는 경우는 발견하지 못했지만, 못하는 것이 아니라 안하는 것일 뿐이겠죠. ^^
1100 (왼쪽에서 오른쪽으로)
0011 (오른쪽에서 왼쪽으로)
'왼편','오른편'이라는 표현을 사용했지만, 사실 이런 상대적인 표현은 정확한 것이 아닙니다. 앞에서 지적했다시피 글자의 방향은 문자를 쓰는 나라마다 자의적으로 변할 수 있으니까 말입니다. 그래서 이런 부정확성을 제거하기위해 컴퓨터 기술자들은 MSB,LSB라는 용어를 이용해서 표현하는데, 우선 MSB,LSB가 의미하는 바를 알아야겠죠?
MSB - Most Significanct Bit (가장 큰 비트 자릿수)
LSB - Least Significant Bit (가장 작은 비트 자릿수)
십진수 12는 이진수 '1100'이라는 이진숫자로 표현되는데, 가장 왼쪽에 나오는 1이라는 비트가 MSB가 됩니다. 반대로 가장 오른쪽에 나오는 비트 0은 LSB가 됩니다.
1 1 0 0
MSB LSB
리틀 엔디안식으로 표현하자면 아래와 같이 위치가 변합니다.
0 0 1 1
LSB MSB
컴퓨터 메모리는 각자 주소를 가지고 있습니다. 우리가 쓰는 IBM PC는 바이트단위로 주소를 할당하는데, 컴퓨터에 따라서는 바이트 단위가 아닌 워드단위(16비트)이상으로 주소를 할당하기도 합니다. 편의적으로 위의 그림에서 왼쪽이 주소가 낮은 쪽, 오른쪽이 주소가 높은 쪽이라고 생각해 봅시다. 그럼 다음과 같은 엔디안의 정의가 가능해집니다.
리틀엔디안 - LSB가 낮은 쪽의 주소에 먼저 등장하는 경우의 비트열
빅엔디안 - MSB가 낮은 쪽의 주소에 먼저 등장하는 경우의 비트열
이제좀 명확해졌습니까??
자.. 지금까지는 바이너리 오더링 다시말해 bit ordering에 관해서 살펴본 것입니다. 엔디안을 살펴볼때, 크게 두가지 체계에서 살펴볼 수 있는데, 첫째가 bit ordering이고 두번째가 byte ordering입니다. 그런데 실제로 문제가 되는 경우는 바이트 오더링이고 비트오더링은 별로 문제가 안됩니다. 왜냐하면, 비트오더링은 대부분의 컴퓨터가 빅엔디안을 채택하고 있기때문입니다. 모토롤라 계열이건, 인텔계열이건 8비트 내부의 비트오더링은 빅엔디안이 거의 표준으로 받아들여져서 사용하기 때문입니다.
다음편에서는 가장 논란의 가져오는 바이트 오더링에 관해서 살펴보겠습니다.
[바이트오더링(Byte Ordering)]
우습잖게도 바이트값들을 더 큰 단위(워드,롱워드,쿼드워드..)로 표현하는 것은 생각지도 않은 큰 차이를 가져옵니다.
사람들이 '엔디안'이라는 이슈로 이야기할때는 바로 '바이트순서'(Byte Ordering)를 문제삼는 것이라고 할 수 있습니다.
서로 다르게 바이트순서를 결정하는 32비트 프로세서를 생각해봅시다.
바이트는 아스키문자를 저장할 수 있는 8비트 한단위라는 것을 잊지맙시다. 그럼 서로 다른 32비트 프로세서가 똑같은 자료를 어떻게 표현하려 하는지를 보기로 하겠습니다.
Big Endian --> 0 1 2 3
U N I X
3 2 1 0 <-- Little Endian
빅엔디안 프로세서가 데이타를 일정한방향으로 저장합니다. 문제는 그와 다른 프로세서가 그 데이타를 읽어들일 경우에 다른 순서로 정렬하려한다는 것입니다. 둘다 32비트 컴퓨터로 가정했을 경우(4바이트를 한단위로 처리하는),한 프로세서가 U-N-I-X라는 순서로 데이타를 쓸경우, 다른 프로세서는 X-I-N-U라는 순서로 읽어들입니다. 큰 문제가 아닐 수 없습니다.
이런 성가신 문제가 처음 등장한 것은 16비트 프로세서였는데,이 경우 한 프로세서가 16비트
단위를 한 단위로 해서 'UN' 'IX'를 쓸 경우에, 다른 프로세서는 'NU', 'XI'라는 짝으로 다시말해
'NUXI'라는 조합을 읽어들입니다. 이것이 바로 유닉스 프로그래머들이 엔디안을 언급할경우에
'NUXI 문제'라고 지칭하는 이유가 되는 것이죠.
이 문제는 단지 문자들에만 영향을 미치는 것은 아닙니다. 바이너리값에도 영향을 미치는데, 많은 값들은 바이트의 조합으로 표현됩니다. 한바이트는 0-255사이의 값을 가지고 있고, 두바이트가(16비트)가 하나의 값을 표현할 경우에는 0-65535(256x256)사이의 값을 가질 수 있습니다. 두바이트중에 한바이트는 'least significant'(하위바이트)라고해서 그대로의 값을 표현하고, 또 한바이트는 'most significant'(상위바이트)라고 해서 자신이 가진 값의 256배를 표현합니다. 가령 한 컴퓨터에서 상위바이트가 50이고 하위바이트가 10이라는 값을 가질경우, 그것이 의미하는 값은 50 x 256 + 10 = 12,810 이 됩니다. 그런데 다른 컴퓨터에서는 상위바이트가 10,하위바이트가 50이 되어 10x256 +50=2,610을 의미하게 되는데 역시 문제가 아닐 수 없습니다.
MSB,LSB라는 것을 바이너리 오더링에서는 Most Significant Bit,Least Significant Bit이라고 했지만, 때로는 Most Significant Byte,Least Significant Byte를 말하기도 합니다. 표현의 문맥을 살펴서 어떤 의미로 쓰여졌는지를 잘 파악해야합니다.
바이트 오더링이 가장 극명하게 문제시되는 분야는 아마 네트웍통신과 파일호환의 문제에서 나타날 것입니다. 가령 맥킨토시에서 파일에 12/34(슬래쉬는 바이트의 구분을 나타냄)라는 값을 쓸경우에 파일에는 1234라고 순서대로 저장되는데, 이 파일을 ibm pc에서 읽어들일 경우에는 34/12라는 값으로 읽어들여서 엉뚱한 값으로 변환되어버립니다. (한바이트 내부의 표현은 대부분 동일하다고 이미 바이너리 오더링 편에서 밝혔습니다.) 이 문제는 응용프로그램의 호환성에도 많은 영향을 미치는데, 이 때문에 파일의 저장형식을 표준화하는 문제가 제기되는 것입니다.
네트웍의 자료교환을 예로 들자면,C의 함수중에는 ntohs,htons,ntohl,htonl등의 바이트 스왑명령어가 존재합니다. 네트웍은 네트웍 바이트 오더링이라고 해서 자료교환의 순서를 표준화했는데, 빅엔디안의 방식에 따릅니다. ibm pc는 리틀엔디안이므로 자료를 보낼때도 바이트 순서를 바꿔야하고, 받을때에도 순서를 바꿔서 해석해야합니다. 단 바이트단위의 전송에는 해당하지 않습니다.
바이트 오더링(엔디안)의 문제에 있어서 현실적이고 단일한 해결방안은 존재하지 않습니다. 서로의 방식을 인정하고 그에 따라 변환하는 수밖에는 딱히 뾰족한 방책이 없지요.
PowerPC같은 프로세서는 'Bi Endian'이라 불리는데,설정에 따라서 빅엔디안도 될 수있고,
리틀엔디안도 될수 있는 프로세서입니다. 하지만 OS는 통상 하나의 엔디안에 의존하게 되므로
동시에 두가지의 엔디안을 쓴다는 것은 큰 의미가 없습니다.
인텔(x86)은 리틀엔디안, 모토롤라(68000's)는 빅엔디안입니다. 맥OS는 빅엔디안, Windows는
리틀엔디안입니다.