본문 바로가기

Dev::Etc/Etc

Big-Endian & Little-Endian

엔디안은 메모리에 저장되는 바이트 순서와 관련이 있다.
예를 들어 0x12345678라는 데이터를 저장한다고 한다면

빅-엔디안에서는 아래와 같이 메모리의 낮은 주소번지에서부터 높은 주소번지로 저장이 된다.

 낮은번지 ----------------> 높은번지

0x12

0x34

0x56

0x78


하지만 리틀-엔디안에서는 빅-엔디안과 반대로 저장을 하게된다.

 낮은번지 ----------------> 높은번지

0x78

0x56

0x34

0x12


보통 빅-엔디안은 매킨토시에 사용되는 모토롤라 CPU가 이 방법을 채택하고 있으면 리틀-엔디안은 우리가 보통 사용하고 있는 Intel계열의 CPU가 이 방법을 사용하고 있다.

빅-엔디안은 사람이 보기에 매우 직관적이다.
하지만 리틀-엔디안도 매우 강력한 장점을 가지고 있다.

예를 들어 2바이트을 4바이트로 확장한다고 한다면

빅-엔디안에서는

0x12

0x34

0x00

0x00

0x12

0x34


위의 그림과 같이 기존의 값을 뒤로 밀어버려야지 제대로된 값을 가진 형확장이 이루어진다.

하지만 리틀-엔디안에서는

0x34

0x12

0x34

0x12

0x00

0x00


위 그림처럼 원래 뒤집혀 있기 때문에 그냥 뒤에 추가만 해주면 형확장이 이루어진다.

소켓 프로그램에서는 엔디안은 매우 중요하다.
서로 다른 엔디안 방법을 사용하는 호스트간에 엔디안을 고려하지 않고 데이터의 전송이
이루어진다면 당연히 보낸 데이터에 대해서 전혀 다른 데이터로 인식하게 될 것이다.
그래서 이러한 문제점을 해결하기 위해서 네트워크를 통해 데이터를 전송할 때는
하나의 엔디안 방식으로 통일하여 데이터를 전송하기로 정하였다.
이것을 네트워크 바이트 순서(Network Byte Order)라 하며 네트워크 바이트 순서로
빅-엔디안만을 사용하기로 약속하였고 리틀-엔디안을 사용하는 시스템에서는 빅-엔디안으로 변환이 필요하다.

WinSock에서는 엔디안을 바꿔주는 함수를 지원한다.
unsigned short htons( unsigned short );
unsigned short ntohs( unsigned short );
unsigned short htonl( unsigned long );
unsigned short ntohl( unsigned long );
hton 는 host to network로 호스트 바이트 순서를 네트워크 바이트 순서로 바꿔준다.
ntoh 는 network to host로 네트워크 바이트 순서를 호스트 바이트 순서로 바꿔준다.
뒤의 s는 short(16bit)이고 l는 long(32bit)이다.

* 간단한 엔디안 확인 소스

참고서적 : C언어 펀더멘탈 , TCP/IP 소켓 프로그래밍