진법
- 진법은 임의의 숫자 혹은 문자를 사용하여 수를 표현하는 체계
- n진법은 한 자릿수를 n가지(0~n-1)의 숫자 혹은 문자로 표현
10진법:10개(0~9)의 숫자로 수를 표현
2진법:2개(0,1)의 숫자로 수를 표현
- 컴퓨터가 사용하는 체계로 컴퓨터의 전기적 신호인 On/Off 상태를 1과0으로 표현
- 0과 1의 조합으로 이루어진 비트(bit)가 모여서 데이터를 표현
- 2진수를 표현할 때는 앞에 0b라는 접두어를 붙임(ex. 10진수 14 = 0b1110)
16진법:16개(0~9, A~F)의 문자로 수를 표현
- 2진법은 수가 조그만 커져도 표현할 때 많은 글자 수가 필요하여 비효율적
- 2진수를 좀 더 간편하고 효율적으로 표현하기 위해 가장 자주 사용되는 표현
- 2진수 4자리를 16진수 한 자리로 표현
- 16진수를 표현할 때 보통 0x라는 접두어를 붙임(ex. 2진수 0b1110 = 16진수 0xC)

비트와 바이트
- 비트와 바이트는 컴퓨터의 데이터를 다루는 데 가장 기본이 되는 개념
- 컴퓨터에서 사용하는 데이터의 최소 단위를 1비트(bit, binary digit)
- 8개의 비트로 구성된 더 큰 단위는 1바이트(byte)라고 하고, 이는 메모리에 저장되는 최소 단위
- 1바이트는 2^8=256가지의 수를 표현

최상위 비트(MSB), 최하위 비트(LSB)
- 여러 개의 비트로 구성된 이진 데이터에서 가장 왼쪽에 있는 비트는 Most Significant Bit(MSB, 최상위 비트), 가장 오른쪽에 있는 비트는 Least Significant Bit(LSB, 최하위 비트)
- 가장 왼쪽에 있는 비트가 숫자의 크기에 가장 큰 영향을, 가장 오른쪽에 있는 비트는 숫자의 크기에 가장 작은 영향을 미치기 때문에 각각의 명명이 붙음
비트 위치 → 8 7 6 5 4 3 2 1
비트 값 → 1 0 0 0 1 0 0 1
MSB LSB
2진수 0b10001001을 나타낸 표현
부호 비트
- 부호가 있는 데이터의 경우, MSB는 부호의 의미를 갖음(MSB가 0이면 양수, 1이면 음수)
- 프로그래밍 언어에서 부호(+,-)를 가지는 데이터는 Signed 데이터 또는 부호가 있는 데이터라 부르고, 부호없이 양수(+)만 나타내는 데이터는 unsigned 데이터 혹은 부호가 없는 데이터라 부름
- ex) 위에서 나온 0b10001001이 Signed 데이터라면 MSB가 1이기 때문에 10진수로 표현하면 -119(-128 + 8 + 1)이고, 부호가 없는 데이터라면 137(128+8+1)이다.
바이트 오더링(Byte Ordering)
- 2바이트 이상의 데이터는 메모리에 연속적으로 저장 -> 이 때 각 바이트가 메모리에 정렬되는 방식을 바이트 오더링(Byte Ordering)이라고 부름
- 바이트 오더링의 두 가지 방식으로 빅 엔디안(Big Endian)과 리틀 엔디안(Little Endian)이 존재
- ex) 0x01234567의 데이터가 존재할 때 가장 왼쪽의 0x01이 가장 큰 바이트이고, 가장 왼쪽의 0x67이 가장 작은 바이트입니다. 빅 엔디안은 큰 바이트로부터 낮은 주소에 저장되고 리틀 엔디안은 작은 바이트로부터 낮은 주소에 저장됩니다.
- MSB, LSB를 통해 빅,리틀 엔디안을 설명하는 자료들이 많은데 해당 경우 Significant Bit를 표현하는 것이 아닌 Significant Byte를 의미(가장 왼쪽의 바이트가 MSB, 가장 오른쪽의 바이트가 LSB)
빅 엔디안(Big-Endian)
- 가장 왼쪽에 있는(큰) 바이트로부터 메모리의 낮은 주소에 저장
- 네트워크 상에서 데이터를 전송할 때는 빅 엔디안 방식
- 대표적으로 SPARC CPU에서 빅 엔디안을 사용

리틀 엔디안(Little-Endian)
- 가장 오른쪽에 있는(작은) 바이트로부터 메모리의 낮은 주소에 저장
- 대표적으로 Intel의 x86, x86-64 CPU에서 리틀 엔디안을 사용
- 대다수의 개인용 컴퓨터 및 서버 환경에서 x86-64를 사용하기에 중요

바이트 오더링 예시
- 데이터가 어떤 바이트 오더링으로 메모리에 저장되었는지 고려하는 것은 기본
- 예를 들어, 리버스 엔지니어링 분야에서 메모리에 저장된 값을 이용해 역연산을 수행하여 어떤 정답이 되는 값을 찾아내는 작업은 매우 흔함, 리틀 엔디안으로 저장된 0x01234567을 빅 엔디안으로 생각하고 0x67452301로 다루게되면 전혀 다른 데이터로 역연산을 수행하는 것
- 시스템 해킹을 예로 들면 공격을 위해 특정 메모리 주소에 원하는 값을 덮어씌움, 낮은 주소부터 값을 쓰는 경우라면 리틀 엔디안을 고려하여 저장하려는 값의 가장 오른쪽 바이트부터 써야 원하는 값이 제대로 저장


- 위를 보면 알 수 있듯이 메모리를 1바이트씩 4바이트를 출력하자 문자열을 메모리에 저장할 때는 바이트 오더링을 고려하지 않음(문자 순서 그대로 메모리에 저장), 16진수 정수의 경우는 리틀 엔디안 방식으로 저장
출처 : https://dreamhack.io/