바이트 순서


CPU 종류 마다 데이터를 저장하는 방법이 다르다.

CPU는 데이터를 메모리에 저장을 한다. 

CPU 마다 데이터 순서를 순방향, 역방향 두 가지 방식으로 저장한다.

순방향 => 빅 엔디안   ( Big Endian )

역방향 => 리틀 엔디안( Little Endian )

사실 순방향, 역방향 이라는 말은 없다. 

설명하기 쉽게 하려고 필자가 만든말이니

이글을 읽는 분은 (빅,리틀) 엔디안만 기억해주기 바란다.


2진수 표현식으로 알아보는 바이트 순서


바이트 순서를 말하기 앞서 바이트가 뭔지 알아야 한다.

1byte = 8bit 이다.  1bit는 0과 1로 구성 되어 있다.

1byte는 00000000 이렇게 표현 가능하다.

정수는 4byte이다. 정수를 bit로 표현하면 다음과 같다.

00000000 00000000 00000000 00000000

정수1은 다음과 같이 표현이 가능하다.

00000000 00000000 00000000 00000001

이우리는 정수1이 CPU마다 어떻게 저장 되는지 알아보겠다.


 Big Endian

 Little Endian 

 00000000 00000000 00000000 00000001

 00000001 00000000 00000000 00000000

 순방향, 읽기 좋은 방향

 역방향, 읽는 순서가 바뀐 방향



메모리 저장 방식으로 알아보는 바이트 순서


CPU 가 메모리에 저장하는 순서를 알아보겠다.

'abcd' 를 저장하는 예를 들어보겠다.

영문은 1byte의 공간을 차지 한다. 메모리 한 블록당 1byte씩 저장한다고 가정 한다.



[BIG Endian]


 a

 b

 c

 d




[Little Endian]


 d

 c

 b

 a




메모리 주소와 바이트 순서

한가지 예를 더 들도록 하겠다. 이번 예는 좀 더 어렵다.

메모리 0x01번지를 시작하는 4바이트 int 정수 0x12345678을 넣도록 하겠다.


4바이트이기 때문에 메모리는 다음과 같은 번지수를 사용한다.


 0x01

 0x02

 0x03

 0x04

작은 번지 수에서 큰 번지수 값을 가진다.


그럼 정수 0x12345678의 최상위 바이트는 0x12이며 최하위 바이트는 0x78이다.


 빅 엔디안   ( Big Endian )

  상위 바이트 값을 작은 번지수에 저장

 리틀 엔디안( Little Endian )

  상위 바이트 값을 큰 번지수에 저장   



[BIG Endian]


  0x01

 0x02

  0x03

  0x04

  0x12

 0x34

  0x56

  0x78



[Little Endian]


  0x01

  0x02

  0x03

  0x04

  0x78

  0x56  0x34  0x12



메모리 저장 순서로 인한 송수신 문제와 해결방법


A,B라고 불리는 두 개의 시스템이 있다. 

서로 데이터를 송수신을 하는 프로그램을 구축했다.

하지만 각각 시스템은 서로 다른 CPU를 사용하여 바이트 저장 순서가 다르다.

그래서 데이터를 송신하면 받는 쪽에서 처리가 불가능 하다.


A시스템에서 0x12, 0x34라고 보냈다. 

B시스템은 0x34, 0x12라고 해석하여 개발자가 의도한데로 동작을 하지 않는다.


[해결방법]

네트워크를 통해 전송할 때는 빅 엔디안 방식으로 통일해서 보낸다.

내 CPU와 상관없이 무조건 송신하기 전에는 빅엔디안으로 보내고 받는쪽에서는 빅엔디안에서 받는쪽 CPU에 맞는 바이트 순서로 바꾼다.



마무리

위에 내용을 자세히 몰라도 프로그램 개발 하는데 지장은 없다.

네트워크를 통해 전송 할 때는 빅 엔디안으로 통일한다는 것만 기억한다.

많은 언어가 비슷한 함수명을 사용하는데 바로 ntoh, hton... 와 같은 이름을 갖은 함수들이다.

송신 전 빅엔디안으로 변환, 수신 후 빅엔디안을 수신쪽 CPU에 맞는 바이트 순서로 바꾸는 함수라 생각하면 된다.





반응형

+ Recent posts