본문 바로가기
Branch/OS

[컴퓨터 구조] 명령어 (고급 언어 vs 저급 언어)

by chung_yu 2026. 2. 4.

1. 고급 언어 vs 저급 언어

컴퓨터는 사실 우리가 쓰는 파이썬이나 자바를 모름. 그래서 '변환'이 무조건 필요함.

  • 고급 언어: 사람이 이해하기 쉬운 언어 (Python, Java, C 등)
  • 저급 언어: 컴퓨터가 직접 이해하고 실행하는 언어
    • 기계어: 0과 1로만 이루어진 비트의 나열
    • 어셈블리어: 0과 1의 나열인 기계어를 사람이 읽기 편하게 문자로 번역함

2. 고급 언어를 실행하는 방식

요즘 언어들은 이 두 방식을 섞어서 쓰기도 하니까, 완전히 나누기보다는 방식의 차이임을 인지할 것.

  • 컴파일 언어: 코드 전체를 한 번에 저급 언어로 변환(컴파일)함.
    • 소스 코드 → 컴파일러 → 목적 코드(저급 언어)
    • 한 번에 확인하니까 오류 체크 좋고 실행 속도가 빠름.
  • 인터프리터 언어: 한 줄씩 실행하며 확인.
    • 소스 코드 전체가 변환되길 기다릴 필요가 없어서 피드백이 빠름.

🛠️ 명령어의 구조 (CPU가 일하는 법)

명령어는 크게 두 부분으로 구성됨: [연산 코드 | 오퍼랜드]

① 연산 코드 (Op-code) 명령어의 '동사'임. CPU가 수행할 동작을 정의함. (데이터 전송, 산술/논리 연산, 제어 흐름 변경, 입출력 제어 등)

연산 코드를 통해 오퍼랜드를 핸들링 하는 건가?
답: YES! 연산 코드가 "뭐 해라" 하면 오퍼랜드에 있는 데이터를 가져오거나 주소를 뒤져서 처리함.

② 오퍼랜드 (Operand) 명령어의 '목적어'임. 연산에 사용할 데이터나 데이터가 저장된 **위치(주소)**가 담김. 주로 위치가 담겨서 주소 필드라고 명칭함.


📍 주소 지정 방식 (유효 주소를 찾는 법)

유효 주소란 연산에 사용할 데이터가 진짜로 저장된 위치를 말함.

  • 즉시 주소 지정 방식: 오퍼랜드에 데이터 자체를 직접 명시 (가장 빠름)
  • 직접 주소 지정 방식: 오퍼랜드에 유효 주소를 직접적으로 명시
    • 유효 주소 크기를 표현할 수 있는 데이터 양에 제한이 있음. 이걸 개선한 게 간접 주소!
  • 간접 주소 지정 방식: 오퍼랜드에 유효 주소의 주소를 명시함.
  • 레지스터 주소 지정 방식: 연산에 사용할 데이터가 저장된 레지스터를 명시함.
    • 💡 레지스터란? CPU 안에 있는 엄청 빠른 임시 저장소. RAM보다 빨라서 당장 필요한 값들 올려두고 씀.

🔍 C언어 컴파일 과정 (중요! 정정 완료)

흐름이랑 파일 확장자 헷갈리지 말 것.

  1. test.c: 소스 코드
  2. 전처리기: #include 등을 처리해서 test.i 생성
  3. 컴파일러: test.i를 어셈블리어 파일인 test.s로 변환 (정정: test.c 아님!)
  4. 어셈블러: 어셈블리어를 기계어(목적 코드)인 test.o로 변환
  5. 링킹: 목적 파일이랑 라이브러리 묶어서 최종 실행 파일(.exe) 완성

 

최종 정리

 

저급언어(기계어)라는 '문장'을 구성하는 '단어'들이 바로 연산코드와 오퍼랜드야.


1. 언어 vs 문장 구조

  • 고급/저급 언어: 이건 **'언어의 종류'**지. (한국어냐, 영어냐, 외계어냐 차이)
  • 연산코드/오퍼랜드: 이건 그 언어로 만든 **'명령어(문장)의 구조'**야.

비유를 들어볼게:

  • 고급언어 (한국어): "사과를 먹어라."
  • 저급언어 (기계어/어셈블리어): "EAT APPLE" (01001 10101...)
  • 여기서 **'먹어라(EAT)'**가 연산코드고, **'사과(APPLE)'**가 오퍼랜드인 거야.

즉, 컴파일러가 고급언어를 저급언어로 번역할 때, 그냥 막 바꾸는 게 아니라 "CPU가 알아먹을 수 있게 [동사(연산코드) + 목적어(오퍼랜드)] 형식을 딱 맞춰서" 번역해주는 거지.

2. 왜 과정을 나눠둔 걸까?

CPU라는 기계 장치는 아주 단순해서, 명령어를 받을 때 **"앞의 몇 비트는 동작(연산코드)으로 읽고, 뒤의 몇 비트는 대상(오퍼랜드)으로 읽자"**라고 약속이 되어 있어.

그래서 저급언어로 변환한다는 건, 결국 CPU의 설계 규칙에 맞게 연산코드와 오퍼랜드라는 칸에 맞춰서 데이터를 채워넣는 작업이라고 보면 돼.

3. 정리하자면

  1. 우리가 고급언어로 코드를 짬.
  2. 컴파일러가 이걸 저급언어로 번역함.
  3. 번역된 저급언어 한 줄 한 줄을 뜯어보니, **연산코드(동작)**와 **오퍼랜드(대상)**로 이루어져 있음.
  4. CPU는 이걸 보고 "아, 이번엔(연산코드) 이 데이터(오퍼랜드)를 쓰면 되는구나!" 하고 실행함.