스킬캠퍼스

오늘 끝나면

명령어와 어셈블리

  • CPU가 아는 명령이 LOAD·ADD·STORE·JUMP처럼 작은 동작뿐이고 fetch, decode, execute를 반복한다는 것을 설명한다
  • JUMP가 PC를 옮겨 위로 되돌리면 같은 명령을 반복하는 루프가 만들어진다는 것을 예로 든다
  • 어셈블리가 기계어(0과 1의 비트)에 1:1로 붙인 사람용 이름표이고 ISA마다 다르다는 것을 말한다

실습 미션

오른쪽 실행기에서 1~5 합산 프로그램을 스텝으로 끝까지 돌려, JUMP가 위로 되돌아가며 같은 명령을 5번 반복해 합 15를 만드는 것을 확인한다.

성공 조건

  • 스텝을 눌러 한 줄씩 PC가 내려가는 것을 봤다
  • JUMP에서 PC가 위 줄로 되돌아가며 루프 도는 것을 봤다
  • 끝났을 때 메모리[1]에 합 15가 쌓인 것을 확인했다

작은 명령 · LOAD·ADD·STORE·JUMP · 어셈블리

명령어와 어셈블리

CPU가 아는 것은 아주 작은 명령 몇 개뿐이다. 우리가 짠 프로그램은 그 작은 명령 묶음으로 번역된다. 어셈블리는 그 명령에 사람이 읽는 이름을 붙인 것이다.

IntelArmRISC-V
P.0115 · 명령어와 어셈블리

CPU가 아는 건 작은 명령뿐이다

CPU는 똑똑해 보이지만 한 번에 하는 일은 어이없이 작다.

메모리에서 값 하나를 꺼내고, 둘을 더하고, 결과를 다시 넣고, 다른 줄로 건너뛴다. 거의 이게 전부다.

그 작은 동작 하나가 명령어다. CPU는 같은 동작만 반복한다. 명령을 가져오고(fetch), 해석하고(decode), 실행한다(execute). 이 한 바퀴를 1초에 수십억 번 돈다.

화려한 게임도 결국 이 작은 명령의 폭포다. 복잡해 보이는 것은 작은 명령을 수없이 이어 붙였기 때문이지, 명령 하나가 똑똑해서가 아니다.

fetch, decode, execute로 이어지는 한 바퀴를 끝없이 반복한다
CPU의 한 바퀴 · 가져오기 → 해석 → 실행
이 세 단계를 1초에 수십억 번 반복함
1
FETCH
가져오기
2
DECODE
해석하기
3
EXECUTE
실행하기
끝나면 다시 처음으로 (끝없는 반복)
PC
0

FETCH , PC가 가리킨 줄의 명령을 메모리에서 꺼냄

명령 하나를 처리하려면 세 단계를 다 거쳐야 함.

P.0215 · 명령어와 어셈블리

네 동사로 거의 다 한다, LOAD·ADD·STORE·JUMP

수많은 명령도 결국 네 종류로 압축된다. 옮기고, 더하고, 되넣고, 건너뛴다.

LOAD는 메모리 값을 레지스터(CPU 안의 임시 저장칸)로 가져온다. STORE는 그 반대로 레지스터 값을 메모리에 되넣는다.

ADD는 레지스터의 두 값을 더한다. 빼기와 곱하기도 다 이 자리에서 일어난다. 계산은 메모리가 아니라 레지스터에서만 한다.

JUMP는 다음에 읽을 줄을 바꾼다. 이 네 동사로 옮기고, 계산하고, 이동하는 거의 모든 계산이 조립된다.

동사를 하나씩 눌러 메모리와 레지스터가 어떻게 움직이는지 본다
네 동사 · 동사를 눌러 무엇이 움직이는지 보기
LOAD A, [0]
메모리
[0]7
[1]3
[2]0
가져옴
레지스터 · PC
A?
B?
PC+1

LOAD, 메모리[0] 값을 레지스터 A로 가져옴

P.0315 · 명령어와 어셈블리

JUMP가 반복을 만든다, 위로 되돌아가기

보통 CPU는 위에서 아래로 한 줄씩 내려가며 실행한다. PC(프로그램 카운터)가 지금 줄을 가리킨다.

JUMP는 그 PC를 강제로 다른 줄로 옮긴다. 아래로 건너뛰면 일부를 건너뛰고, 위로 되돌리면 같은 명령을 다시 한다.

위로 되돌리는 JUMP가 바로 루프다. '5를 1까지 줄이며 더해라' 같은 일을, 같은 몇 줄을 5번 돌려 처리한다.

조건부 점프(JZ, 0이면 점프)를 끼우면 '언제 멈출지'까지 정한다. 갈림길(if)과 반복(loop)이 전부 이 한 동작에서 나온다.

JUMP 대상 줄을 바꿔 위로 되돌아가는 루프를 직접 만들어본다
JUMP = 흐름 바꾸기 · 대상 줄을 움직여보기
0LOAD A, [0]
1ADD A, [1]
2STORE A, [2]
3SUB B, [3]
4JUMP 1
JUMP 대상 줄1
01234

루프위(1줄)로 되돌아감 → 같은 명령을 다시 함 = 루프

위로 되돌리는 JUMP가 곧 반복임. 조건부 점프(JZ)를 끼우면 언제 멈출지까지 정함.

P.0415 · 명령어와 어셈블리

어셈블리 = 기계어에 붙인 이름표

CPU가 진짜 읽는 것은 0과 1의 숫자다. ADD 한 줄도 메모리에는 0001 0011 같은 비트로 적혀 있다. 사람 눈에는 외계어다.

그래서 그 숫자 명령마다 사람이 읽는 이름을 붙인다. LOAD, ADD, JUMP. 이게 어셈블리다. 1947년경 등장해 0과 1을 손으로 적던 코딩을 끝냈다.

어셈블리는 기계어와 거의 1:1로 대응한다. 이름표만 붙였지 하는 일은 그 숫자 명령 그대로다. 어셈블러가 이름을 다시 비트로 옮긴다.

Intel과 Arm, RISC-V는 각자 다른 명령어 집합(ISA)을 가진다. 그래서 같은 ADD라도 칩마다 다른 비트로 적히고, 어셈블리도 칩마다 사투리가 다르다.

기계어 비트와 어셈블리 이름을 토글하며 1:1 대응을 확인한다
어셈블리 = 기계어에 붙인 이름표
CPU가 진짜 읽는 건 0·1 비트임. 사람은 이름으로 읽음, 둘은 1:1.
사람이 읽음ADD R0, R0, R1
CPU가 읽음•••• •••• •••• ••••

어셈블러가 이름 한 줄을 이 비트로 바꿔 줌. 하는 일은 똑같음, 이름표만 붙였을 뿐.

같은 ADD인데 칩(ISA)마다 문법도 비트도 다름

ADD R0, R0, R1

Arm, RISC, 명령 폭이 고정됨

P.0515 · 명령어와 어셈블리

직접 어셈블리 실행해보기

오른쪽 실행기에서 1~5 합산 프로그램을 스텝으로 한 줄씩 직접 돌려본다.

스텝을 누르면 PC가 가리킨 줄이 실행되고, 레지스터 A와 B, 메모리 칸이 그때그때 바뀌는 것이 보인다.

핵심은 JUMP 줄이다. 2줄로 되돌아가며 같은 명령 몇 줄을 5번 반복해, 합 15(=1+2+3+4+5)를 쌓아 올린다.

외우지 말고 끝까지 돌려본다. '1부터 5까지 더해라'라는 사람 말이, 이 작은 명령 묶음으로 번역돼 굴러가는 것이 손에 잡힌다.

스텝으로 한 줄씩 실행하면 PC가 내려가고, JUMP에서 위로 되돌아가며 레지스터와 메모리가 바뀌어 합 15가 쌓이는 것이 보인다.
미니 어셈블리 실행기 · 1~5 합산 루프
프로그램, PC가 가리킨 줄을 한 번에 하나씩 실행
0
LOAD A, [1] ; A = 합(0)
1
LOAD B, [0] ; B = 카운터 N
2
JZ B, 7 ; B==0 이면 끝(7줄)로
3
ADD A, [0] ; A = A + B(현재 카운터)
4
SUB B, [2] ; B = B - 1
5
STORE B, [0] ; 줄어든 B를 메모리에
6
JUMP 2 ; 2줄로 되돌아감(루프)
7
STORE A, [1] ; 합을 메모리[1]에 저장
8
HALT ; 멈춤

파란 줄 = 다음에 실행할 명령(PC) · 연한 칸 = 방금 실행한 줄

레지스터 & PC, CPU 안의 임시 저장칸
PC
0
레지스터 A
0
레지스터 B
0
메모리, [0]=카운터 · [1]=합 · [2]=1
[0]
5
[1]
0
[2]
1
[3]
0

스텝을 눌러 한 줄씩 실행해보셈. CPU는 이 작은 명령(LOAD·ADD·STORE·JUMP)만 앎. JUMP가 위로 되돌아가며 같은 명령을 5번 반복하는 게 루프임.

3줄 요약

  1. 1CPU가 아는 것은 LOAD·ADD·STORE·JUMP 같은 아주 작은 명령뿐이고, fetch, decode, execute를 끝없이 반복한다.
  2. 2JUMP는 PC를 옮기는 명령이라, 위로 되돌리면 루프가 되고 조건을 끼우면 갈림길이 된다.
  3. 3어셈블리는 기계어 비트에 사람이 읽는 이름을 1:1로 붙인 것이다. ISA마다 같은 ADD도 다른 비트로 적힌다.

완료 전 점검

복습 카드

명령어

CPU가 한 번에 하는 최소 동작 (LOAD·ADD·STORE·JUMP 등)

레지스터

CPU 안의 임시 저장칸. 계산은 여기서만 한다

PC(프로그램 카운터)

지금 실행할 줄을 가리키는 표시. JUMP가 이것을 바꾼다