먼저 알아야 할 것
- 진법과 자릿수 (공학수학 대학수학): 2진수와 16진수 읽기. 문서의
과목별 관점에 16진 덧셈·뺄셈이 있다 - 정수의 2진 표현과 2의 보수, 부호와 부호화 (2-1학기 자료와 정보): 음수 적는 법과 ASCII
- 불 대수와 논리 회로 (공학수학 이산수학): AND·OR·NOT과 진리표
- 컴퓨터 구조 내용 일부는 운영체제 문서(컴퓨터의 기본 구성 요소, 명령어 사이클)의
과목별 관점에 합쳤다. 번호 원칙으로는 먼저 배우는 이 과목이 번호를 가져야 하지만 이미 정리된 문서의 번호를 바꾸지 않았다.
이 지식베이스의 실행 결과는 MASM이 아니라 파이썬으로 레지스터·플래그·스택을 흉내 내 확인했다.
어셈블리어 소개와 가상 기계
읽기 전에
- C++ 한 줄
cout << (A * B + C);는 프로세서가 실행하는 명령 몇 개쯤이 될까? → 어셈블리어와 기계어 - 어셈블리어로 쓴 프로그램을 다른 종류의 프로세서에서 그대로 돌릴 수 있을까? → 어셈블리어와 기계어
- 사람이 쓰기 편한 말로 쓴 프로그램을 기계가 돌리는 방법 두 가지는? → 가상 기계 계층
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 01 | 어셈블리어와 기계어 | 기계어 명령 하나에 이름 하나를 붙인 말. 한 줄이 기계어 한 개 | verify | 16진 계산과 2의 보수 연습 · 문제 코드 |
| 02 | 가상 기계 계층 | 고급 언어 → 어셈블리어 → 기계어 → 논리 회로로 내려가는 네 층 | verify | — |
떠올려 보기: 노트를 닫고 사람의 말, C++, 어셈블리어, 기계어 네 가지가 서로 어떻게 바뀌는지 그려 본다.
기계 단계, 수와 문자 표현, 불 연산
읽기 전에
- C++ 프로그램과 논리 게이트 사이에 층이 몇 개 있을까? → 가상 기계 계층
6A + 4B를 10진수로 바꾸지 않고 계산할 수 있을까? → 진법과 자릿수- 16진수
9D가 음수인지 한 글자만 보고 알 수 있을까? → 정수의 2진 표현과 2의 보수
개념: 진법·2의 보수·문자 부호·불 연산은 진법과 자릿수, 정수의 2진 표현과 2의 보수, 부호와 부호화, 불 대수와 논리 회로 문서의 과목별 관점에 합쳤다. 연습은 위 01번 줄의 16진 계산과 2의 보수 연습에 있다.
떠올려 보기: 네 단계의 이름, 16진 덧셈의 올림 규칙, 2의 보수 만드는 두 단계를 적고 서로 어디서 만나는지 써 본다.
x86 프로세서 구조
읽기 전에
- 걸음이 6개인 프로세서가 명령어 100개를 겹쳐 처리하면 600사이클보다 얼마나 줄까? → 파이프라인과 슈퍼스칼라
- EAX에
12345678h가 있을 때 AL에FFh를 넣으면 EAX는 얼마가 될까? → x86 레지스터 - 16비트 레지스터로 1MB 메모리의 주소를 어떻게 다 가리킬까? → 실주소 모드의 세그먼트 주소
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 03 | 파이프라인과 슈퍼스칼라 | 명령어를 걸음으로 나눠 겹쳐 처리한다. \(k + (n - 1)\)사이클 | verify | — |
| 04 | x86 레지스터 | 프로세서 안의 이름 붙은 저장 칸. 범용 8개, 세그먼트 6개, EFLAGS, EIP | verify | — |
| 05 | x86 동작 모드 | 실주소 모드(1MB, 보호 없음), 보호 모드(4GB, 프로그램마다 구역), 가상 8086 모드 | verify | — |
| 06 | 실주소 모드의 세그먼트 주소 | 선형 주소 = 세그먼트 × 16 + 오프셋 | verify | — |
| 07 | 입출력 접근 수준 | 입출력을 라이브러리·운영체제·BIOS·하드웨어 가운데 누구에게 부탁하나 | — | — |
떠올려 보기: 레지스터의 종류, 세 가지 동작 모드, 입출력의 네 단계를 적고 “보호 모드에서는 무엇이 막히는가”로 이어 본다.
어셈블리 문법, 데이터 정의, 데이터 전송
읽기 전에
- 16진수
A5를 코드에A5h라고 쓰면 어셈블러는 무엇으로 읽을까? → 어셈블리 문장의 구성 .data와mov eax,5가운데 프로세서가 실행하는 줄은 어느 쪽일까? → 지시어와 명령어 비교- 내 원본에 없는
DumpRegs의 코드는 언제, 누가 내 프로그램에 붙일까? → 어셈블·링크·실행 과정
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 08 | 어셈블리 문장의 구성 | 한 줄은 레이블, 니모닉, 피연산자, 주석 네 칸 | verify | — |
| 09 | 지시어와 명령어 비교 | 어셈블러가 따르는 줄과 프로세서가 실행하는 줄 | — | — |
| 10 | 프로그램 틀 | 모든 프로그램이 올라타는 뼈대. .data, .code, main PROC, END main |
verify | — |
| 11 | 어셈블·링크·실행 과정 | 원본 → 목적 파일 → 실행 파일 → 메모리. 어셈블러, 링커, 로더 | verify | — |
| 12 | 데이터 정의 | 이름, 칸 크기, 처음 값을 적어 메모리에 변수를 잡는다 | verify | — |
| 13 | 리틀 엔디언 | 여러 바이트 값은 아랫자리 바이트가 낮은 주소에 온다 | verify | — |
| 14 | 기호 상수와 위치 카운터 | 수에 이름을 붙이고, $로 배열 크기를 어셈블러가 세게 한다 |
verify | — |
| 15 | 피연산자의 종류 | 명령의 재료는 즉시값, 레지스터, 메모리 셋이고 이름+수는 주소를 옮긴다 | verify | — |
| 16 | 데이터 전송 명령 | MOV는 복사, XCHG는 맞바꾸기. 크기가 같아야 하고 메모리끼리는 안 된다 | verify | — |
| 17 | 제로 확장과 부호 확장 | 작은 값을 넓힐 때 윗자리를 0으로 채우거나 부호 비트로 채운다 | verify | — |
떠올려 보기: 노트를 닫고 “변수를 정의한다 → 메모리에 바이트로 놓인다 → 명령이 그 자리를 가져다 쓴다”의 세 단계를 val1 DWORD 12345678h 하나로 써 본다.
덧셈·뺄셈과 플래그, 데이터 연산자, 간접 주소, JMP·LOOP
읽기 전에
- AL에 FFh를 넣고 1을 더하면 00h가 된다. 이 계산은 맞았을까 틀렸을까? CPU는 그것을 어떻게 알려 줄까? → 산술 연산과 상태 플래그
mov ax,00FFh뒤에inc ax와inc al을 각각 하면 AX는 같아질까? → 덧셈·뺄셈 명령myDouble DWORD 12345678h에서mov ax,WORD PTR myDouble은 1234h를 가져올까 5678h를 가져올까? → OFFSET과 PTR 연산자
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 18 | 덧셈·뺄셈 명령 | INC·DEC·ADD·SUB·NEG. 계산은 적은 칸의 크기 안에서만 일어난다 | verify | 산술식을 어셈블리로 옮기기 연습 · 문제 코드 |
| 19 | 산술 연산과 상태 플래그 | 계산마다 결과가 0인지, 음수인지, 넘쳤는지를 ZF·SF·CF·OF로 남긴다 | verify | 플래그 추적 예제 사다리 · 문제 코드 |
| 20 | 올림 플래그와 넘침 플래그 비교 | 부호 없는 수의 넘침은 CF, 부호 있는 수의 넘침은 OF로 본다 | — | — |
| 21 | OFFSET과 PTR 연산자 | OFFSET은 변수의 주소를 주고, PTR은 정의와 다른 크기로 읽게 한다 | verify | PTR과 리틀 엔디언 예제 사다리 · 문제 코드 |
| 22 | TYPE·LENGTHOF·SIZEOF 연산자 | 원소 크기, 원소 개수, 전체 바이트 수. \(\text{SIZEOF} = \text{LENGTHOF} \times \text{TYPE}\) | verify | — |
| 23 | 간접 피연산자와 인덱스 피연산자 | 주소를 레지스터에 넣고 [esi]나 배열[esi]로 칸을 옮겨 가며 읽는다 |
verify | — |
| 24 | JMP와 LOOP | JMP는 무조건 넘어가고 LOOP는 ECX를 먼저 줄인 뒤 0이 아니면 되돌아간다 |
verify | LOOP로 배열 돌기 예제 사다리 · 문제 코드 |
떠올려 보기: 노트를 닫고 네 플래그(ZF, SF, CF, OF)가 켜지는 조건을 쓰고, CF와 OF가 서로 다른 값이 되는 8비트 덧셈을 하나씩 만들어 본다.
스택과 프로시저
읽기 전에
- ESP가 00001000h일 때 32비트 값 하나를 올리면 ESP는 커질까 작아질까, 얼마가 될까? → 런타임 스택과 PUSH·POP
- 프로시저가 끝났을 때 CPU는 어디로 돌아가야 하는지를 어떻게 알까? → 프로시저와 CALL·RET
- 프로시저 안에서
push만 하고pop을 빼먹은 채ret을 만나면 어디로 갈까? → 프로시저와 CALL·RET
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 25 | 런타임 스택과 PUSH·POP | 올리면 ESP가 4 줄고 내리면 4 는다. 거꾸로 꺼내야 제자리 | verify | — |
| 26 | 프로시저와 CALL·RET | CALL은 돌아올 주소를 스택에 올리고 RET은 맨 위 값을 EIP로 내린다 |
verify | 스택 추적 예제 사다리 · 문제 코드 |
| 27 | 레지스터 매개변수와 USES | 자료 위치를 레지스터로 받고, 지킬 레지스터는 USES로 치웠다 되돌린다 |
verify | — |
떠올려 보기: 노트를 닫고 PUSH, POP, CALL, RET이 각각 ESP와 스택에 하는 일을 쓰고, 겹쳐 부른 프로시저 셋이 돌아오는 순서를 스택 그림으로 그려 본다.
Irvine32 라이브러리, 비트 논리·비교, 조건 점프
읽기 전에
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 28 | Irvine32 라이브러리 | 약속된 레지스터에 값을 넣고 call로 부르는 입출력 도구 48개 |
verify | — |
| 29 | 비트 논리 명령 | AND로 끄고 OR로 켜고 XOR로 뒤집는다 |
verify | — |
| 30 | TEST와 CMP | 값은 그대로 두고 플래그만 남기는 뺄셈(CMP)과 AND(TEST) |
verify | — |
| 31 | 조건 점프 | 플래그를 보고 갈라 가는 점프. 부호 있는 “작다”는 \(\text{SF} \ne \text{OF}\) | verify | — |
| 32 | 부호 있는 비교 점프와 부호 없는 비교 점프 | 같은 비트를 above·below는 부호 없이, greater·less는 부호 있게 읽는다 | verify | — |
떠올려 보기: 노트를 닫고 부호 없는 비교 점프 넷과 부호 있는 비교 점프 넷을 쓰고, 각각 어떤 플래그를 보는지와 CMP·TEST가 그 플래그를 어떻게 만드는지 이어 본다.
조건부 반복, 조건 구조, 유한 상태 기계
읽기 전에
- 배열에서 첫 양수를 찾는 루프는 “찾았을 때”와 “끝까지 봤을 때” 두 가지로 멈춘다. 멈춘 뒤 어느 쪽인지 무엇으로 가릴까? → 조건부 반복 명령
if (a <= b) { … }를 옮길 때cmp뒤에 “이하면 점프”를 쓸까, “초과면 점프”를 쓸까? → 조건 구조를 점프로 옮기기- 글자에 따라 부를 프로시저가 스무 가지면
cmp·je를 스무 번 쓰는 것 말고 어떤 방법이 있을까? → 표 기반 선택
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 33 | 조건부 반복 명령 | 남은 횟수와 ZF를 함께 보고 되돌아가는 LOOPZ·LOOPNZ |
verify | — |
| 34 | 조건 구조를 점프로 옮기기 | 조건을 뒤집어 “거짓이면 건너뛰어라”로 if·while을 옮긴다 |
verify | 조건 구조를 점프로 옮기기 예제 사다리 · 문제 코드 |
| 35 | 표 기반 선택 | 값과 프로시저 주소를 짝지은 표를 훑어 갈림을 대신한다 | verify | — |
| 36 | 유한 상태 기계 | 상태마다 이름표, 화살표마다 비교와 조건 점프로 옮기는 입력 검사기 | verify | 유한 상태 기계 연습 · 문제 코드 |
떠올려 보기: 노트를 닫고 부호 있는 정수를 알아보는 상태 그림을 그린 뒤, 상태 A를 어셈블리 코드로 옮겨 본다.
시프트와 회전, 스택 프레임
읽기 전에
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 37 | 시프트 명령 | 비트를 한쪽으로 밀어 \(2^n\)을 곱하거나 나누고, 밀려난 비트는 CF에 남긴다 | verify | — |
| 38 | 논리 시프트와 산술 시프트 비교 | 오른쪽으로 밀 때 빈칸을 0으로 채우면 부호 없는 수, 부호 비트로 채우면 부호 있는 수 | — | — |
| 39 | 회전 명령 | 밀려난 비트가 반대쪽으로 돌아오는 밀기, RCL·RCR은 CF까지 한 고리 | verify | — |
| 40 | 이중 시프트 SHLD·SHRD | 빈칸을 다른 레지스터의 비트로 채워 두 레지스터에 걸친 수를 민다 | verify | 시프트와 회전 예제 사다리 · 문제 코드 |
| 41 | 스택 프레임 | 호출 하나가 스택에 차지하는 구역, EBP를 고정해 \([\mathrm{EBP}+8]\)부터 매개변수를 읽는다 | verify | — |
| 42 | 스택 매개변수 | 인수를 스택에 넣어 넘긴다. 값을 넣으면 사본, 주소를 넣으면 원본을 고친다 | verify | — |
떠올려 보기: 노트를 닫고 시프트·회전 명령 여덟 개가 빈칸을 무엇으로 채우는지 표로 쓰고, push 6, push 5, call AddTwo 뒤의 스택을 주소와 함께 그려 본다.
호출 규약, 지역 변수, 재귀
읽기 전에
- 스택에 쌓은 인수는 프로시저가 끝난 뒤 누가 치울까? 양쪽이 서로 미루면 어떻게 될까? → 호출 규약
- 지역 변수의 주소는 왜
OFFSET으로 구할 수 없을까? → OFFSET과 LEA 비교 - Factorial의 코드는 한 벌인데, 3!을 구하는 동안 \(n\) = 3, 2, 1, 0은 각각 어디에 들어 있을까? → 재귀 프로시저
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 43 | 호출 규약 | 쌓은 인수를 부른 쪽이 치우는가(C, add esp,n) 불린 쪽이 치우는가(STDCALL, ret n) |
verify | — |
| 44 | 지역 변수 | sub esp,n으로 만들고 mov esp,ebp로 없애는 \([\mathrm{EBP}-4]\) 아래의 임시 칸 |
verify | 스택 프레임 그리기 예제 사다리 · 문제 코드 |
| 45 | OFFSET과 LEA 비교 | 번역할 때 정해지는 주소는 OFFSET, 실행해 봐야 아는 주소는 LEA | verify | — |
| 46 | INVOKE·PROC·PROTO 지시어 | push·call·\([\mathrm{EBP}+8]\)을 어셈블러가 대신 써 주는 지시어 | verify | — |
| 47 | 재귀 프로시저 | 자기를 다시 부르는 프로시저, 호출마다 12바이트 프레임에 \(n\)을 따로 둔다 | impl | 재귀 호출 스택 추적 연습 · 문제 코드 |
떠올려 보기: 노트를 닫고 Factorial(3)이 가장 깊이 들어갔을 때의 스택 열두 칸을 그리고, 돌아오면서 EAX가 바뀌는 순서를 써 본다.
디스크 구조와 FAT
읽기 전에
- 4,096바이트 단위로만 자리를 내주는 디스크에 8,200바이트 파일을 넣으면 몇 바이트가 버려질까? → 클러스터와 FAT
- 파일 조각이 디스크 여기저기에 흩어져 있으면 운영체제는 다음 조각이 어디인지 어떻게 알까? → 클러스터와 FAT
- 파일 이름 없이 디스크의 섹터를 번호로 바로 읽는 함수는 왜 요즘 Windows에서 막혀 있을까? → INT 21h 파일·디스크 함수
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 48 | 클러스터와 FAT | 파일은 클러스터 단위로 나뉘고 FAT에 적힌 “다음 번호”를 따라 이어진다 | verify | — |
| 52 | INT 21h 파일·디스크 함수 | 파일은 핸들로 다루고 실패는 올림 플래그로 알며, 섹터 직접 읽기는 실주소 모드에서만 된다 | verify | — |
52번은 이 묶음에서 다루지만, 다음 묶음의 INT 21h를 먼저 알아야 해서 번호가 뒤에 있다. 트랙·섹터·실린더는 운영체제의 디스크 스케줄링 문서의 과목별 관점에 합쳤다.
떠올려 보기: 노트를 닫고 섹터, 클러스터, 클러스터 사슬, FAT, 디렉터리가 파일 이름에서 섹터까지 어떻게 이어지는지 그려 본다.
16비트 MS-DOS와 INT 21h
읽기 전에
- 1MB 메모리의 맨 아래 1,024바이트에는 무엇이 들어 있을까? → MS-DOS 메모리 배치
- BIOS의 화면 코드는 컴퓨터마다 다른 주소에 있는데, 같은 프로그램이 어떻게 어디서나 그 코드를 부를까? → INT 명령과 인터럽트 벡터 표
- 글자 찍기와 날짜 읽기가 둘 다
int 21h라면 MS-DOS는 무엇을 보고 둘을 구별할까? → INT 21h 입출력 함수
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 49 | MS-DOS 메모리 배치 | 1MB 주소 공간에 벡터 표, DOS, 프로그램, 화면 메모리, ROM BIOS가 정해진 주소로 놓인다 | verify | — |
| 50 | INT 명령과 인터럽트 벡터 표 | INT n은 주소 \(n \times 4\)의 칸에서 처리 코드 주소를 찾아 갔다가 IRET로 돌아온다 |
verify | — |
| 51 | INT 21h 입출력 함수 | AH에 함수 번호를 넣고 INT 21h를 불러 글자·문자열·날짜를 읽고 쓴다 |
verify | — |
떠올려 보기: 노트를 닫고 int 21h를 부르는 세 단계와, int 명령을 만난 프로세서가 처리 코드까지 가서 돌아오는 네 걸음을 써 본다.
BIOS 키보드·비디오, 인터럽트 핸들러
읽기 전에
- F1이나 화살표 키에는 ASCII 코드가 없다. 프로그램은 이런 키를 어떻게 알아볼까? → BIOS 키보드 입력 INT 16h
- 파란 바탕에 밝은 회색 글자를 1바이트로 적으면 얼마일까? → BIOS 비디오 INT 10h와 속성 바이트
- 키보드와 타이머가 동시에 프로세서를 부르면 누가 먼저 처리될까? 누가 정할까? → 하드웨어 인터럽트와 IRQ
| 번호 | 개념 | 한 줄 | 개념 코드 | 연습 |
|---|---|---|---|---|
| 53 | BIOS 키보드 입력 INT 16h | 누른 키는 스캔 코드와 ASCII 쌍으로 버퍼에 쌓이고 INT 16h로 꺼낸다 |
verify | — |
| 54 | BIOS 비디오 INT 10h와 속성 바이트 | 속성 바이트 = (바탕 SHL 4) OR 글자색, INT 10h로 색 글자를 쓰고 화면을 지운다 |
verify | — |
| 55 | 하드웨어 인터럽트와 IRQ | 장치의 요청은 8259가 IRQ 우선순위로 걸러 보내고 CLI·STI로 막고 연다 |
verify | — |
| 56 | 인터럽트 핸들러 바꿔 끼우기 | 벡터 표의 칸을 내 코드 주소로 바꾸고, 일을 마치면 원래 핸들러로 넘긴다 | verify | — |
떠올려 보기: 노트를 닫고 키 하나가 눌린 뒤 프로그램이 받기까지의 길(포트, 8259, 벡터 표, INT 9h, 버퍼, INT 16h)과, 그 길에 내 핸들러를 끼우는 네 단계를 써 본다.
다른 과목과의 연결
- 스택 프레임, 호출 규약 ↔ 활성 레코드, 함수 호출의 코드 생성 (3-2학기 컴파일러): 사람이 손으로 짜는 호출 코드와 컴파일러가 만들어 내는 호출 코드
- 유한 상태 기계 ↔ 유한 오토마타 (3-2학기 컴파일러): 같은 상태 그림을 점프로 옮기느냐 표로 돌리느냐
- 조건 구조를 점프로 옮기기 ↔ 3주소 코드 (3-2학기 컴파일러): if와 while을 레이블과 점프로 편다
- 산술 연산과 상태 플래그 ↔ 연산자와 오버플로 (2-1학기 소프트웨어 프로젝트): Java는 넘쳐도 말이 없고 CPU는 CF·OF로 남긴다
- INT 명령과 인터럽트 벡터 표, 클러스터와 FAT ↔ 인터럽트, 파일 할당 (3-1학기 운영체제): 운영체제 원리의 x86·MS-DOS 사례
흐름
graph TD
C1["01 어셈블리어와 기계어"]
C2["02 가상 기계 계층"]
C3["03 파이프라인과 슈퍼스칼라"]
C4["04 x86 레지스터"]
C5["05 x86 동작 모드"]
C6["06 실주소 모드의 세그먼트 주소"]
C7["07 입출력 접근 수준"]
C8["08 어셈블리 문장의 구성"]
C9["09 지시어와 명령어 비교"]
C10["10 프로그램 틀"]
C11["11 어셈블·링크·실행 과정"]
C12["12 데이터 정의"]
C13["13 리틀 엔디언"]
C14["14 기호 상수와 위치 카운터"]
C15["15 피연산자의 종류"]
C16["16 데이터 전송 명령"]
C17["17 제로 확장과 부호 확장"]
C18["18 덧셈·뺄셈 명령"]
C19["19 산술 연산과 상태 플래그"]
C20["20 올림 플래그와 넘침 플래그 비교"]
C21["21 OFFSET과 PTR 연산자"]
C22["22 TYPE·LENGTHOF·SIZEOF 연산자"]
C23["23 간접 피연산자와 인덱스 피연산자"]
C24["24 JMP와 LOOP"]
C25["25 런타임 스택과 PUSH·POP"]
C26["26 프로시저와 CALL·RET"]
C27["27 레지스터 매개변수와 USES"]
C28["28 Irvine32 라이브러리"]
C29["29 비트 논리 명령"]
C30["30 TEST와 CMP"]
C31["31 조건 점프"]
C32["32 부호 있는 비교 점프와 부호 없는 비교 점프"]
C33["33 조건부 반복 명령"]
C34["34 조건 구조를 점프로 옮기기"]
C35["35 표 기반 선택"]
C36["36 유한 상태 기계"]
C37["37 시프트 명령"]
C38["38 논리 시프트와 산술 시프트 비교"]
C39["39 회전 명령"]
C40["40 이중 시프트 SHLD·SHRD"]
C41["41 스택 프레임"]
C42["42 스택 매개변수"]
C43["43 호출 규약"]
C44["44 지역 변수"]
C45["45 OFFSET과 LEA 비교"]
C46["46 INVOKE·PROC·PROTO 지시어"]
C47["47 재귀 프로시저"]
C48["48 클러스터와 FAT"]
C49["49 MS-DOS 메모리 배치"]
C50["50 INT 명령과 인터럽트 벡터 표"]
C51["51 INT 21h 입출력 함수"]
C52["52 INT 21h 파일·디스크 함수"]
C53["53 BIOS 키보드 입력 INT 16h"]
C54["54 BIOS 비디오 INT 10h와 속성 바이트"]
C55["55 하드웨어 인터럽트와 IRQ"]
C56["56 인터럽트 핸들러 바꿔 끼우기"]
C1 --> C2
C1 --> C3
C1 --> C4
C4 --> C5
C5 --> C6
C5 --> C7
C1 --> C8
C4 --> C8
C8 --> C9
C8 --> C10
C9 --> C10
C10 --> C11
C8 --> C12
C10 --> C12
C12 --> C13
C9 --> C14
C12 --> C14
C4 --> C15
C12 --> C15
C13 --> C15
C15 --> C16
C16 --> C17
C16 --> C18
C18 --> C19
C19 --> C20
C13 --> C21
C15 --> C21
C16 --> C21
C12 --> C22
C21 --> C23
C22 --> C23
C18 --> C23
C4 --> C24
C23 --> C24
C4 --> C25
C16 --> C25
C24 --> C25
C25 --> C26
C24 --> C26
C26 --> C27
C25 --> C27
C26 --> C28
C27 --> C28
C19 --> C29
C19 --> C30
C29 --> C30
C30 --> C31
C24 --> C31
C19 --> C31
C31 --> C32
C30 --> C32
C24 --> C33
C31 --> C33
C25 --> C33
C31 --> C34
C32 --> C34
C30 --> C34
C34 --> C35
C26 --> C35
C14 --> C35
C23 --> C35
C31 --> C36
C30 --> C36
C26 --> C36
C29 --> C37
C19 --> C37
C37 --> C38
C37 --> C39
C19 --> C39
C37 --> C40
C39 --> C40
C25 --> C41
C26 --> C41
C23 --> C41
C41 --> C42
C27 --> C42
C21 --> C42
C41 --> C43
C42 --> C43
C26 --> C43
C41 --> C44
C21 --> C44
C12 --> C44
C21 --> C45
C44 --> C45
C42 --> C46
C43 --> C46
C44 --> C46
C41 --> C47
C42 --> C47
C43 --> C47
C31 --> C47
C5 --> C49
C6 --> C49
C49 --> C50
C26 --> C50
C6 --> C50
C50 --> C51
C4 --> C51
C51 --> C52
C48 --> C52
C50 --> C53
C49 --> C53
C50 --> C54
C50 --> C55
C55 --> C56
C51 --> C56
C53 --> C56