본문 바로가기

ROS

[코스모스 9주차] 컴퓨터 과학

1. 진법

  • 임의의 숫자 혹은 문자를 사용하여 수를 표현하는 체계
  • n진법은 한 자리 수를 n가지(0~n-1)의 숫자 혹은 문자로 나타낼 수 있음
    • 10진법
      • 사람들이 자연스럽게 사용하고 있는 수 체계
    • 2진법
      • 컴퓨터는 2진법을 사용
      • 0과 1의 조합으로 이루어진 비트가 모여서 데이터를 표현
      • 2진수를 표현할 때는 보통 0b라는 접두어를 붙임
      • ex) 10진수 14 → 2진수 0b1110
    • 16진법
      • 2진수를진 좀 더 간편하고 효율적으로 표현하기 위해 쓰인 진법 중 하나
      • ex) 2진수 0b1100 → 16진수 0xC
      • 프로그램을 분석할 때 사용하는 디버깅 도구 같은 경우, 일반적으로 메모리의 위치를 나타내는 주소값을 16진수 형태로 출력
      • RGB 색상을 표현할 때도 16진수 형태로 표기

2. 비트와 바이트

  • 비트와 바이트는 컴퓨터의 데이터를 다루는 데 가장 기본이 되는 개념
  • 컴퓨터는 0과 1만으로 데이터를 표현하고 처리
  • 0과 1을 나타내는, 컴퓨터에서 사용하는 데이터의 최소 단위를 1비트라고 함
  • 8개의 비트로 구성된 더 큰 단위는 1바이트 → 메모리에 저장되는 최소 단위
  • 1바이트는 2의 8승 = 256 가지의 수를 표현할 수 있음
  • 10진수로 0~255, 2진수로 00000000~11111111, 16진수로 00~FF까지 나타냄

 

  • 최상위 비트(MSB)
    • 여러 개의 비트로 구성된 이진 데이터에서 가장 왼쪽에 있는 비트
    • 가장 왼쪽에 있는 비트가 숫자의 크기에 가장 큰 영향을 미침
  • 최하위 비트(LSB)
    • 여러개의 비트로 구성된 이진 데이터에서 가장 오른쪽에 있는 비트
    • 가장 오른쪽에 있는 비트는 숫자의 크기에 가장 작은 영향을 미침
  • 0b10010100( 10010100 )의 MSB는 1이고, LSB는 0

 

  • 부호 비트
    • 부호가 있는 데이터의 경우, MSB는 부호의 의미를 가지게 됨
    • MSB가 0이면 양수, 1이면 음수
    • 부호를 가지는 데이터는 Signed 데이터 또는 부호가 있는 데이터라고 함
    • 부호없이 양수만 나타내는 데이터는 unsigned 데이터 또는 부호가 없는 데이터라고 함

 

  • 바이트 오더링
    • 2바이트 이상의 데이터는 메모리에 연속적으로 저장됨
    • 이때 각 바이트가 메모리에 정렬되는 방식으 ㄹ바이트 오더링이라고 함
    • 바이트 오더링 방식
      • 빅 엔디안(Big Endian)
        • 큰 바이트부터 낮은 주소에 저장됨
      • 리틀 엔디안(Little Endian)
        • 작은 바이트부터 낮은 주소에 저장됨
    • 빅 엔디안, 리틀 엔디안을 설명할 때의 MSB, LSB는 앞서 배운대로 Significant Bit을 의미하는 것이 아니라 Significant Byte를 의미함
    • 바이트 오더링은 비트의 순서가 아니라 바이트의 순서를 고려하는 것으로, 바이트 내 비트의 순서는 동일하고 바이트의 순서만 달라짐.
      • 가장 왼쪽에 있는 바이트를 MSB
      • 가장 오른쪽에 있는 바이트를 LSB
  • 빅 엔디안
    • 가장 왼쪽에 있는(큰) 바이트부터 메모리의 낮은 주소에 저장됨
      • 네트워크 상에서 데이터를 전송할 때는 빅 엔디안 방식을 따름
      • 대표적으로 SPARC CPU에서 빅 엔디안을 사용함

Big Endian

  • 리틀 엔디안
    • 가장 오른쪽에 있는(작은) 바이트부터 메모리의 낮은 주소에 저장됨
      • 대표적으로 Intel의 x86, x86-64 CPU에서 리틀 엔디안을 사용
      • 대다수의 개인용 컴퓨터 및 서버 환경에서 x86-64 CPU 아키텍처를 사용하고 있는 만큼, 리틀 엔디안 방식을 잘 알고 있어야함

Little Endian

  • 바이트 오더링 예시
    • 메모리에 저장된 값을 이용해 역연산을 수행하여 어떤 정답이 되는 값을 찾아내는 작업은 매우 흔함
    • 이때 메모리에 저장된 값이 어떤 엔디안으로 저장되어 있는지를 고려하지 않으면, 전혀 다른 데이터로 혼동하여 올바른 역연산 결과를 얻을 수 없게 됨

바이트 오더링 예시

위 사진은 문자열과 16진수 정수를 메모리에 저장하는 C 프로그램의 소스 코드

 

  • 문자열
    • str 변수 주소의 메모리를 1바이트씩 4바이트 출력한 결과
    • 문자열을 메모리에 저장할 때는 바이트 오더링을 고려하지 않음
    • 따라서, 문자열 "ABCD"는 리틀 엔디안 방식을 따르지 않고, 문자 순서 그대로 메모리에 저장됨

  • 문자열이 아닌 데이터 - 16진수 정수
    • num 변수 주소의 메모리를 1바이트씩 4바이트 출력한 결과
    • 문자열이 아닌 데이터는 리틀 엔디안 방식으로 저장됨
    • 따라서 16진수 0x41424344는 가장 오른쪽의 바이트부터 메모리의 낮은 주소에 저장된 것을 볼 수 있음
    • num 변수 값을 출력하면 메모리에 저장된 4바이트에서 높은 주소부터 읽어 와서 원래 값 그대로 출력됨


3. 비트 연산

  • 비트 연산
    • 2진수로 표현하여 비트 단위로 연산하는 것을 비트 연산이라고 함
    • 비트 단위로 논리 연산을 수행하거나, 비트를 특정 값만큼 이동하는 시프트(shift) 연산을 수행함
  • 논리 연산
    • 참 또는 거짓 값으로 연산을 수행하고 결과로 참(1, true) 또는 거짓(0, false)을 반환함

  • 비트 연산자
    • 비트 단위로 논리 연산을 수행함
    • 1은 참, 0은 거짓을 나타냄

  • 비트 연산자 OR (|)
    • 대응하는 비트 중 하나라도 1이면 1이 됨
    • 둘 다 1이 아닌 경우에만 0이 됨

  • 비트 연산자 AND(&) 
    • 대응하는 비트가 모두 1이어야 1이 되며, 하나라도 1이 아니면 0이 됨

  • 비트 연산자 XOR(^)
    • 대응하는 비트가 서로 다르면 1이 됨
    • 서로 같으면 0이 됨

  • 비트 연산자 NOT(~)
    • 0은 1이 되고, 1은 0이 됨

  • 시프트 연산자
    • 비트를 특정 값만큼 왼쪽 혹은 오른쪽으로 이동함
    • n만큼 시프트한 결과는 2의 n승으로 곱하거나 나눈 값과 같음

왼쪽 시프트 연산
오른쪽 시프트 연산
산술 시프트
논리 시프트
논리 시프트

  • 비트 연산 활용
    • And (&) 연산 활용한 비트 마스킹
      • 비트 마스킹 : 어떤 데이터가 존재할 때, 특정 위치의 비트만 표시하거나 가리는 연산
      • 0XABCD에 0X00FF를 AND 연산을 하면 0XCD만 남길 수 있음

  • AND (&) 연산과 시프트 연산을 활용하여 특정 비트/바이트 가져오기
- 하위 1 바이트만 가져오기
0x12345678 & 0x000000FF = 0x00000078 (0000 0000 0000 0000 0000 0000 0111 1000)
- 상위 1 바이트만 가져오기
0x12345678 >>> 24 = 0x00000012 (0000 0000 0000 0000 0000 0000 0001 0010)
0x12345678 >> 24 & 0x000000FF = 0x00000012 (0000 0000 0000 0000 0000 0000 0001 0010)
- 상위에서 두 번째 바이트 가져오기
0x12345678 >> 16 & 0x000000FF = 0x00000034 (0000 0000 0000 0000 0000 0000 0011 0100)
- 하위 1 바이트의 상위 4비트 가져오기
0x12345678 >> 4 & 0x0000000F = 0x00000007 (0000 0000 0000 0000 0000 0000 0000 0111)
  • XOR 연산을 활용한 비교와 암호화
    • XOR 연산은 비트 값이 같으면 0 반환 → 자기 자신과 XOR 연산하면 결과는 0
    • 어떤 값을 2번 XOR 하면 원래의 값과 동일해짐
      • x^y 결과가 z 라고 하면, z^y = x^y^y = x
      • y를 key로 설정하면 간단한 암호화, 복호화 가능
  • 시프트 연산을 활용한 곱셈, 나눗셈
    • 2의 n승을 곱하거나 나눈 결과와 동일함
    • 시프트 연산을 사용하면 비트 레벨에서 연산을 하므로 더 효율적이고 속도가 빠름