스킬캠퍼스

오늘 끝나면

어셈블러와 실행

  • 어셈블러와 실행의 핵심 문제를 한 문장으로 설명한다
  • 오른쪽 실습에서 어셈블러와이 어떻게 움직이는지 관찰한다
  • 다음 강의와 이어지는 한계를 말할 수 있다

실습 미션

어셈블리→기계어→메모리 적재→Step 디버깅 이 문장이 실제로 무슨 뜻인지 실습에서 한 번 손으로 확인한다.

성공 조건

  • 실습의 기본값을 먼저 관찰
  • 입력값이나 모드를 한 번 이상 바꿔 결과 비교
  • 왜 결과가 바뀌었는지 한 문장으로 설명

반도체 설계 · 19

어셈블러와
실행

기계어 비트는 사람이 못 읽는다.
사람이 읽는 명령인 어셈블리를 비트로 바꾸는 프로그램이 어셈블러다.
메모리에 적재하고, Step으로 실행하고, breakpoint로 멈춰 본다.

P.01반도체 설계 · 19

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

16강에서 정한 명령 포맷은 결국 비트 다발이다. 0010 001 010 000000 같은 16비트 한 줄을 사람이 외울 수는 없다.

그래서 비트마다 사람이 읽는 이름을 붙인다.
opcode 0010ADD, 레지스터 번호는 R1·R2다.
그 한 줄이 ADD R1, R2이고, 이것이 어셈블리다.

어셈블리는 기계어와 거의 일대일이다. 명령 하나가 비트 한 워드에 대응한다.
파이썬처럼 한 줄이 수십 줄로 풀리지 않는다. 그래서 CPU가 실제로 뭘 하는지 가장 가까이서 볼 수 있다.

사람이 읽는 한 줄 → 16비트 한 워드
한 줄 → 한 워드(16비트)
사람이 읽는 어셈블리

ADD R1, R2

↓ 어셈블러
CPU가 읽는 기계어, 16비트
0010
opcode
ADD
001
rA
R1
010
rB
R2
000000
imm

= 0x2280 = 0010001010000000

명령 1줄이 비트 1워드. 어셈블리는 기계어에 이름만 붙인 것이다
P.02반도체 설계 · 19

어셈블러가 번역을 한다

어셈블리를 기계어로 바꿔주는 작은 프로그램이 어셈블러다. CPU는 비트만 읽으니 누군가는 번역을 해야 한다.

어셈블러가 하는 일은 두 가지다.
하나, 니모닉을 opcode로 바꾼다. ADD0010으로 바꾸고, 레지스터와 상수를 각 필드 자리에 끼운다.
둘, label로 주소를 관리한다.

사람은 점프할 곳을 loop: 같은 이름으로 적는다. 몇 번째 주소인지 셀 필요가 없다.
어셈블러가 코드를 한 번 훑어 label이 몇 번 줄인지 적어두고(1차 패스), 다시 훑으며 그 이름을 실제 주소로 바꾼다(2차 패스).

니모닉·label → opcode·주소
어셈블러, 두 번 훑어 번역
1차 패스

줄을 세며 label이 몇 번 주소인지 적어둔다

2차 패스

니모닉을 opcode로, label을 주소로 인코딩

00MOVI R1, 5
01loop: ADDI R1, -1label = 주소 01
02BEQZ R1, endend → 주소 04
03JMP looploop → 주소 01
04end: HLTlabel = 주소 04
사람은 loop·end 이름만 적고, 주소 계산은 어셈블러가 한다
P.03반도체 설계 · 19

메모리에 적재하고 Step으로 실행

번역된 기계어는 명령메모리에 한 줄씩 쌓인다. 이걸 적재라고 한다. 실행은 PC가 그 줄들을 한 칸씩 짚는 것이다.

한 스텝의 골격은 18강 싱글사이클 CPU와 같다.
PC가 가리키는 주소에서 명령을 꺼내고(인출), 무슨 명령인지 읽고(디코드), 데이터패스로 굴린(실행) 다음 PC를 다음 칸으로 옮긴다.
분기나 점프면 PC가 다음 칸 대신 다른 주소로 튄다.

이걸 사람이 보려고 한 명령씩 멈추는 것이 Step이다.
Step을 누를 때마다 PC가 한 칸 가고, 그 명령이 바꾼 레지스터와 메모리가 눈에 보인다.
코드 한 줄과 CPU 상태가 줄 단위로 이어진다. 칩이 진짜로 뭘 하는지 그제야 보인다.

PC가 한 칸씩 인출·디코드·실행
한 스텝 = PC 한 칸 + 인출·디코드·실행
한 명령의 세 박자
인출 · PC 주소에서 명령 꺼냄
디코드 · opcode·필드 해석
실행 · 데이터패스로 굴림
명령메모리, PC가 짚는 줄PC = 01
00MOVI R1, 5
01MOVI R2, 4
02ADD R1, R2
03HLT
Step마다 ▶ 한 칸 이동. 분기나 점프면 다음 칸 대신 다른 주소로 튄다
P.04반도체 설계 · 19

직접 짜서 한 줄씩 실행해본다

코드를 고치고 ASSEMBLE을 누르면 한 줄씩 16비트로 번역돼 메모리에 적재된다.

STEP은 한 명령씩만 나아간다. 누르면 방금 바뀐 레지스터와 메모리 칸만 진하게 칠해진다.

코드 줄 왼쪽 를 누르면 breakpoint(◆)가 된다.
RUN은 breakpoint 줄을 실행하기 직전까지 자동으로 달리고 거기서 멈춘다. 의심 가는 줄만 골라 멈춰 까보는 것이 디버깅이다.
아래 근거 패널은 다음 명령을 opcode·rA·rB·imm 필드로 쪼개 보여준다. 코드 한 줄이 어떤 비트가 되는지 확인한다.

어셈블리 편집 → ASSEMBLE → STEP·RUN·breakpoint
어셈블리 플레이그라운드 · MY-16
어셈블리, 사람이 읽는 명령. 고치고 ASSEMBLE

STEP = 한 명령씩 · RUN = breakpoint(◆)까지 자동 · 코드 줄 왼쪽 ○를 눌러 breakpoint

ASSEMBLE을 누르면 위 코드가 한 줄씩 16비트 기계어로 번역돼 메모리에 적재된다. 그게 어셈블러가 하는 일이다.

P.05반도체 설계 · 19

breakpoint = 의심 가는 줄에서 멈추기

코드가 길어지면 한 줄씩 STEP만 누르긴 지친다. 그래서 멈추고 싶은 줄에 표시를 박는데, 그것이 breakpoint다.

RUN을 누르면 CPU가 명령을 빠르게 연달아 실행한다.
그러다 breakpoint가 박힌 줄을 실행하기 직전에 딱 멈추고, 그 순간의 레지스터와 메모리를 들여다본다.
값이 이상하면 거기서부터 STEP으로 한 줄씩 까보면 어디서 틀렸는지 잡힌다.

코드인 왼쪽과 CPU 상태인 오른쪽을 잇는 것이 디버깅의 전부다.
어느 줄을 실행했더니 어느 레지스터가 어떻게 바뀌었나, 이 연결만 보이면 버그는 보인다.

Q. 어셈블러가 하는 일은?사람이 읽는 명령인 어셈블리를 CPU가 읽는 기계어(비트)로 번역하는 일이다.
니모닉을 opcode로 바꾸고 레지스터와 상수를 각 필드에 끼운다.
label은 실제 주소로 풀어준다. 사람은 이름만 적고 주소 계산은 어셈블러가 한다.
RUN으로 달리다 ◆ 에서 정지
RUN → breakpoint(◆)에서 정지
00MOVI R1, 5실행됨
01MOVI R2, 4실행됨
02ADD R1, R2여기서 멈춤
03ST [R3], R1
04HLT
◆ 줄을 실행하기 직전에 정지한다. 그 순간 레지스터와 메모리를 들여다본다

3줄 요약

  1. 1어셈블리→기계어→메모리 적재→Step 디버깅
  2. 2어셈블러와 실행은 비트·게이트 → ALU → 시간·메모리 → 나만의 CPU → 메모리·GPU·SoC 흐름 안의 한 칸이다.
  3. 3개념을 외우는 것보다 입력을 바꾸면 무엇이 달라지는지 보는 것이 우선이다.

완료 전 점검

복습 카드

어셈블러와

어셈블리→기계어→메모리 적재→Step 디버깅

ALU

산술·논리 연산을 하는 회로

ISA

CPU가 이해하는 명령어 집합과 인코딩