목록

2019년 6월 8일 토요일

리틀 엔디언(Little endian)과 빅 엔디언(Big endian)의 차이



endian 은 endianness 를 말합니다.

많은 분들이 리틀 엔디언과 빅 엔디언을 헷갈려 하시는것 같아서
이 글에선 이해하기 쉬운 그림을 그려 첨부해 봅니다.


엔디언의 정의
 엔디언(Endianness)은 컴퓨터 메모리와 같은 1차원의 공간에 여러 개의 연속된 대상을 배열하는 방법을 뜻하며, 바이트를 배열하는 방법을 특히 바이트 순서(Byte order)라 한다.
엔디언은 보통 큰 단위가 앞에 나오는 빅 엔디언(Big-endian)과 작은 단위가 앞에 나오는 리틀 엔디언(Little-endian)으로 나눌 수 있으며, 두 경우에 속하지 않거나 둘을 모두 지원하는 것을 미들 엔디언(Middle-endian)이라 부르기도 한다.


바이트 순서
 바이트 순서는 크게 빅 엔디언과 리틀 엔디언으로 나눌 수 있다. 빅 엔디언은 사람이 숫자를 쓰는 방법과 같이 큰 단위의 바이트가 앞에 오는 방법이고, 리틀 엔디언은 반대로 작은 단위의 바이트가 앞에 오는 방법이다. PDP-11과 같은 몇몇 아키텍처는 2바이트 단위와 1바이트 단위로 서로 다른 순서를 사용하기도 하는데 이들을 미들 엔디언이라 부른다.

다음은 32비트 정수. 16진법 값 0x12345678 이 0x1000 주소에 있을 때, 메모리 상에 어떻게 들어가는지를 나타내는지 보여주는 그림입니다.
각 바이트는 8비트라고 가정


빅 엔디언은 낮은 주소에 높은자리 값이 들어가는 방식이고
리틀 엔디언은 낮은 주소에 낮은자리 값이 들어가는 방식입니다.
위 이미지에서 값과 비트 값은 동일 하지만 메모리 주소와 주소가 증가하는 방향을 유심히 보세요.


------- 안 읽어도 되는 부분 (개인 이야기) -------

보통의 경우는 리틀 엔디언을 설명할 때 아래 그림처럼 설명하더군요

메모리 주소의 증가방향은 빅 엔디언과 똑같이 보여주고
값이 거꾸로 된 모습으로 설명하더라구요.
하지만 저는 이 방식이 너무 불편했습니다.
값을 거꾸로 보는것도 불편하고, 비트 쉬프트를 한다고 가정했을 때 너무 계산 방식이 더러웠습니다.

비트를 왼쪽으로 8비트 쉬프트 하겠다 했을 때를 가정해 봅시다.
(부호 없는 정수라고 가정)
0x12345678 << 8
이것의 결과는 C언어로 확인해보시거나 암산해보셨다면 0x34567800 을 기대하실겁니다.
하지만 메모리 주소 증가 방향이 좌에서 우로 가는 방향이라면
왼쪽이 아닌 오른쪽으로 8비트 쉬프트 해야 같은 결과가 나옵니다.

바이트 단위로 쉬프트 한다면 그냥 이렇게 끝나겠는데, 4비트만 쉬프트 해본다고 생각해봅시다.
0x12345678 << 4
결과는 0x23456780 이죠.
하지만 위와 같은 메모리 주소 증가 방향이라면 우로 4비트 쉬프트 해도
00000111 10000101 01100011 01000001
이가 나오고 이 값은 0x41638507 이 되버리는 군요.
제대로 계산하려면 비트를 거꾸로 뒤집어서 계산하면 됩니다.
안그래도 자주 까먹기 쉬운데 이래가지고는 머리만 아프죠.

여러분들은 제가 위쪽에 올린 그림을 보셔서 스트레스 받지 마시기 바랍니다.

------- 안 읽어도 되는 부분 끝 ------

장단점

 빅 엔디언은 소프트웨어의 디버그를 편하게 해 주는 경향이 있다. 사람이 숫자를 읽고 쓰는 방법과 같기 때문에 디버깅 과정에서 메모리의 값을 보기 편한데, 예를 들어 0x59654148은 빅 엔디언으로 59 65 41 48로 표현된다.
 반대로 리틀 엔디언은 메모리에 저장된 값의 하위 바이트들만 사용할 때 별도의 계산이 필요 없다는 장점이 있다. 예를 들어, 32비트 숫자인 0x2A는 리틀 엔디언으로 표현하면 2A 00 00 00이 되는데, 이 표현에서 앞의 두 바이트 또는 한 바이트만 떼어 내면 하위 16비트 또는 8비트를 바로 얻을 수 있다. 반면 32비트 빅 엔디언 환경에서는 하위 16비트나 8비트 값을 얻기 위해서는 변수 주소에 2바이트 또는 3바이트를 더해야 한다. 보통 변수의 첫 바이트를 그 변수의 주소로 삼기 때문에 이런 성질은 종종 프로그래밍을 편하게 하는 반면, 리틀 엔디언 환경의 프로그래머가 빅 엔디언 환경에서 종종 실수를 일으키는 한 이유이기도 하다.
 또한 가산기가 덧셈을 하는 과정은 LSB로부터 시작하여 자리 올림을 계산해야 하므로, 첫 번째 바이트가 LSB인 리틀 엔디언에서는 가산기 설계가 조금 더 단순해진다. 빅 엔디언에서는 가산기가 덧셈을 할때 마지막 바이트로부터 시작하여 첫 번째 바이트까지 역방향으로 진행해야 한다. 그러나 오늘날의 프로세서는 여러개의 바이트를 동시에 읽어들여 동시에 덧셈을 수행하는 구조를 갖고 있어 두 엔디언 사이에 사실상 차이가 없다.


요약
빅 엔디언은 낮은 주소에 높은자리 값이 들어가는 방식
리틀 엔디언은 낮은 주소에 낮은자리 값이 들어가는 방식
오늘날의 대부분의 CPU는 리틀엔디언 방식 채택
리틀엔디언은 하위 바이트를 획득하기 위해 높은 자료형에서 낮은 자료형으로 변환 할 때 별도의 계산이 필요없다. 빅 엔디언의 경우 주소를 바꿔서 읽거나 쉬프트하여야 함




- 구문 인용, 참고 : 위키 백과

댓글 없음:

댓글 쓰기

목록