리틀엔디언 VS 빅엔디언
엔디언이란 무엇인가?
엔디언(Endianness)은 컴퓨터의 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.
엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있으며, 두 경우에 속하지 않거나 둘을 모두 지원하는 것을 미들 엔디언(Middle-endian)이라 부르기도 한다.
빅 엔디안은 최상위 바이트(MSB - Most Signficant Byte)부터 차례로 저장하는 방식이며, 리틀 엔디안은 최 하위 바이트(LSB - Least Significant Byte) 부터 차례로 저장하는 방식이다.
그렇다면 최 상위와 최 하위라는 것은?
뭔가 공감이 되지 않는 설명인데, 이런 설명이 조금 더 씌여있다.
빅 엔디언은 사람이 숫자를 쓰는 방법과 같이 큰 단위의 바이트가 앞에 오는 방법이고
리틀 엔디언은 반대로 작은 단위의 바이트가 앞에 오는 방법이다.
빅 엔디언 <- 높은 주소 - - - - 낮은 주소 - >
리틀 엔디언 <- 낮은 주소 - - - - 높은 주소 - >
즉 단순히 12345678이 87654321과 같이 거꾸로 저장된다기 보다는..
해당 수치를 데이터의 단위 단위로 나누었을 때 그 단위가 거꾸로 배열되는 형태인듯 하다.
메모리의 0에서부터 끝으로 쓰는 방식이 빅 엔디안.
메모리의 끝에서부터 0으로 쓰는 방식이 리틀 엔디안이라 할 수 있다.
오늘날 x86 아키텍처를 사용하는 대부분의 데스크톱 컴퓨터는 리틀 엔디언을 쓰며 이를 ‘인텔 포맷’이라 한다. 거꾸로 네트워크에서는 주소를 빅 엔디언으로 쓰는데, 역사적으로 라우팅이 전화를 거는 식으로 접두 부호로 이루어졌기 때문이다.
장단점
빅 엔디언은 소프트웨어의 디버그 를 편하게 해 주는 경향이 있다. 사람이 숫자를 읽고 쓰는 방법과 같기 때문에 디버깅 과정에서 메모리의 값을 보기 편한데, 예를 들어 0x59654148은 빅 엔디언으로 59 65 41 48로 표현된다.
반대로 리틀 엔디언은 메모리에 저장된 값의 하위 바이트들만 사용할 때 별도의 계산이 필요 없다는 장점이 있다. 예를 들어, 32비트 숫자인 0x2A는 리틀 엔디언으로 표현하면 2A 00 00 00 이 되는데, 이 표현에서 앞의 두 바이트 또는 한 바이트만 떼어 내면 하위 16비트 또는 8비트를 바로 얻을 수 있다. 반면 32비트 빅 엔디언 환경에서는 하위 16비트나 8비트 값을 얻기 위해서는 변수 주소에 2바이트 또는 3바이트를 더해야 한다 . 보통 변수의 첫 바이트를 그 변수의 주소로 삼기 때문에 이런 성질은 종종 프로그래밍을 편하게 하는 반면, 리틀 엔디언 환경의 프로그래머가 빅 엔디언 환경에서 종종 실수를 일으키는 한 이유이기도 하다.
또한 가산기가 덧셈을 하는 과정은 LSB로부터 시작하여 자리 올림을 계산해야 하므로, 첫 번째 바이트가 LSB인 리틀 엔디언에서는 가산기 설계가 조금 더 단순해진다. 빅 엔디언에서는 가산기가 덧셈을 할때 마지막 바이트로부터 시작하여 첫 번째 바이트까지 역방향으로 진행해야 한다. 그러나 오늘날의 프로세서는 여러개의 바이트를 동시에 읽어들여 동시에 덧셈을 수행하는 구조를 갖고 있어 두 엔디언 사이에 사실상 차이가 없다.
엔디안 방식이 중요해지는 것은 네트워크인데.데이터 전송을 할 때 엔디안 방식의 차이에 주의해야 한다. 서로 다른 데이터 저장 방식의 시스템끼리 통신하게 되면 전혀 엉뚱한 값을
주고받기 때문이다.
네트웍 데이터 통신에서는 네트워크 바이트 순서(network byte order, 빅 엔디안)를
따르도록 데이터의 바이트 순서를 변경해야 한다.
(TCP/IP, XNS, SNA 규약은 16비트와 32비트 정수에서 빅 엔디안 방식을 사용함)
이럴 때에 htonl 같은 함수(host to network)를 이용해서 바이트 순서를 정렬시켜주면 된다.
몇몇 아키텍처는 빅 엔디언과 리틀 엔디언 중 하나를 선택할 수 있도록 설계되어 있고, 이를 바이 엔디언(Bi-endian)이라 부른다.
종종 한 방향으로 순서가 정해져 있는 게 아니라, 이를테면 32비트 정수가 2바이트 단위로는 빅 엔디언이고 그 안에서 1바이트 단위로는 리틀 엔디언인 경우가 종종 있는데 이를 미들 엔디언(Middle-endian)이라 한다.
둘이 차이점은 계산할때와 비교할 때 눈에 띈다.
빅 엔디언을 통한 숫자 비교시, 숫자의 비교는 가장 큰 값이 들어가는 왼쪽부터 하게 되는데, 빅 엔디언은 수치를 앞에서부터 차곡차곡 스택에 집어 넣는 반면 리틀 엔디언으로 하게된다면 리틀 엔디언은 숫자 뒤에서부터 스택에 집어 넣기 때문이 빅 엔디언보다 속도가 느리다.
그러나 수치 계산시에는 리틀 엔디안이 빅 엔디안보다 속도가 더 빠른데 두 숫자를 계산을 할 경우 가장 낮은 자리수에 있는 숫자를 계산을 해보고서 자리 올림수가 있는지 없는지 판단을 하고서 자리 올림수와 다음 숫자를 계산을 하기 때문이다.
빅 엔디언은 UNIX 에서 사용하는 RISC 프로세서에서 사용 하는 바이트 오더, 동시에 소켓 프로그래밍에서 중요한 네트워크 바이트 오더, 리틀 엔디언은 Intel 계열의 프로세서에서 사용하는 바이트 오더이다.
빅 엔디안 | 리틀 엔디안 |
Unix 의 RISC계열의 프로세서가 사용하는 바이트 오더링 네트워크에서 사용하는 바이트 오더링 앞에서부터 스택에 PUSH 비교연산에서 리틀 엔디안보다 속도가 빠름 | Intel 계열의 프로세서가 사용하는 바이트 오더링
뒤에서부터 스택에 PUSH 계산연산에서 빅 엔디안보다 속도가 빠름 |
출처 및 참고
: 위키백과