본문 바로가기

Computer Science/Computer Architecture

[Computer Architecture] 명령어 집합 (1)

+ 한국항공대학교 길현영 교수님의 컴퓨터구조론 과목 내용을 정리한 글입니다.

Fake Simple 컴퓨터 명령어 집합 (가정)

< 명령어 >

명령어 연산 부호 (16진법) 의미
LDA (Load) 1 메모리의 내용을 누산기(CPU)에 적재
STA (Store) 2 누산기(CPU)의 내용을 메모리에 저장
ADD (Add) 3 누산기의 내용과 메모리의 내용을 덧셈 (누산기에 저장)
SUB (Subtract) 4 누산기의 내용에서 메모리의 내용을 뺄셈
(누산기에 저장)
JMP (Jump) 5 지정한 주소로 분기
CAL (Call) 6 프로시저 호출
HLT (Halt) 8000 프로그램 종료
CPL (Complement) 8001 누산기의 내용을 보수화
IAC (Increase AC) 8002 누산기의 내용을 하나 증가
RET (Return) 8005 프로시저 복귀

+ 16진법 한 자리수는 2진법 네 자리 수로 표현 가능

ex) 8000 => 1000 0000 0000 0000

< 명령어 형식>

1. 16 bit로 구성되어있다. (가정)

2.  연산 부호4bit 혹은 16bit이다.

- 15번 bit = 0 이면, 12 ~ 15번 bit가 연산 부호이다.  ex) LDA ~ CAL

- 15번 bit = 1 이면, 0 ~ 15번 bit가 연산 부호이다. ex) HLT ~ RET

=> 첫 번째 bit (15번 bit)만 보고 CPU가 처리할 수 있다! (처리 속도 ↑)

< 데이터 형식 >

1. 16 bit로 구성하고 정수만 취급한다.

2. 15번 bit는 부호를 의미하고, 0 ~ 14번 bit는 정수 크기 의미한다. (최상위 bit)

(15번 bit가 0이면 양수, 1이면 음수이다.)

데이터 형식

< 메모리 상태 >

1. 명령어는 메모리 0100 (16진법) 번지부터 시작한다.

2. 데이터는 메모리 0500 번지와 0502 번지에 숫자(정수 데이터) 0001, 0002이 저장되어있다.

 

각 entry(방) 별로 하나의 주소 값을 갖고, 1 Byte데이터를 저장한다. (가정)

+ 명령어의 크기가 2byte (16bit) 이므로 다음 명령어가 저장될 메모리 주소는 0100 -> 0102가 된다.

(연속된 두 개의 entry를 사용한다. 즉 인자에 시작 주소와 몇 바이트의 데이터인지 전달한다.)

 

현재 메모리 상태를 그리는 중간고사 문제 출제!!

=> 명령어와 데이터 모두 그려야한다. (모두 메모리에 올라와 있어야 한다.)

< 문제 >

메모리 0500번지와 0502번지 숫자를 더해 0502번지에 저장하고, 0300번지 명령어로 분기하라!

1. M[500] + M[502] -> M[502]

2. PC <- 300

 

메모리 주소 명령어 (16진법) 기계어 (16진법) 상태
0100 LDA 500 1500 500번지의 수 누산기에 적재
0102 ADD 502 3502 누산기의 수 +  502번지의 수 
0104 STA 502 2502 누산기의 수 502번지에 저장
0106 JMP 300 5300 0300번지 명령어로 분기

명령어 단위의 수행 과정

위 문제에서 LDA 500 (1500) 명령어 수행 과정 - 0100

1. CPU에서 메모리 0100에 저장된 1500이라는 명령을 수행하기 위해 PC(Program Counter)에 0100이 저장된다. (CPU는 PC가 가리키는 주소에 가서 명령어를 가져온다. 명령어들의 시작 주소를 가리키도록 세팅)

1500 수행 과정 1

2 - 1. PC가 가리키는 명령어 주소를 MAR에 저장하고, CPU에서 메모리에 제어신호와 함께 MAR에 저장된 주소를 주소 버스를 통해 전달한다. 

2 - 2. 메모리는 MAR에 저장된 주소에 있는 데이터(명령어)를 데이터 버스를 통해 CPU의 MBR로 전달한다.

2 - 3. MBR에 있는 데이터는 일반적인 데이터가 아닌 명령어 데이터이기 때문에 IR에 저장된다.

=> 인출 사이클 (Fetch Cycle)

1500 수행 과정 2

3 - 1. IR에 저장된 명령어의 15 bit ~ 12 bit (OpCode)을 해독한다.

3 - 2. 이전까지 PC는 현재 수행하는 명령어를 갖고 있으므로, 다음 명령어를 가리키기 위해 PC에 2byte(16bit, 명령어의 크기)를 더한다. (0100 -> 0102. ALU 사용)

1500 수행 과정 3

4 - 1. 해독한 명령어를 실행한다.

4 - 2. IR에 저장된 명령어의 11 bit ~ 0 bit (Operand) 값을 MAR에 저장하고, 메모리에 MAR에 저장된 주소를  전달한다. 

4 - 3. 메모리는 MAR에 저장된 주소(0500)에 있는 데이터(0001)를 데이터 버스를 통해 CPU의 MBR로 전달한다.

4 - 4. MBR에 있는 데이터를 ACC에 저장한다.

=> 실행 사이클 (Execution Cycle: 전송 연산) 

1500 수행 과정 4

축약: MAR <- PC; MBR <- M[MAR]; IR <- MBR = IR <- M[PC]

위 문제에서 ADD 502 (3502) 명령어 수행 과정 (축약) - 0102

1. IR <- M[PC] 

=> PC가 가리키는 주소의 명령어를 메모리에서 읽어와서 IR에 저장한다.

 

2. PC <- PC + 2; decode IR[15:12]

=> IR에 저장된 명령어의 OpCode를 해독하고 PC가 다음 명령어를 가리키도록 한다. (0102 -> 0104)

 

3. Acc <- Acc + M[IR[11:0]]

=> 0100에서 수행하여 Acc에 저장된 0001과 IR의 Operand에 저장된 주소의 메모리에 저장된 0003을 더하여 Acc에 저장한다.

3500 수행 과정

위 문제에서 STA 502 (2502) 명령어 수행 과정 (축약) - 0104

1. IR <- M[PC] 

=> PC가 가리키는 주소의 명령어를 메모리에서 읽어와서 IR에 저장한다.

 

2. PC <- PC + 2; decode IR[15:12]

=> IR에 저장된 명령어의 OpCode를 해독하고 PC가 다음 명령어를 가리키도록 한다. (0104 -> 0106)

 

3. M[IR[11:0]] <- Acc

=> 0102에서 수행하여 Acc에 저장된 0003을 IR의 Operand에 저장된 주소의 메모리에 저장한다.

 

+ CPU가 메모리에 Write 제어신호와 함께 MAR에 저장할 주소를, MBR에 저장할 데이터를 보낸다.

2502 수행 과정

위 문제에서 JMP 300 (5300) 명령어 수행 과정 (축약) - 0106

1. IR <- M[PC] 

=> PC가 가리키는 주소의 명령어를 메모리에서 읽어와서 IR에 저장한다.

 

2. PC <- PC + 2; decode IR[15:12]

=> IR에 저장된 명령어의 OpCode를 해독하고 PC가 다음 명령어를 가리키도록 한다. (0106 -> 0108)

 

3. PC <- IR[11:0]

=> IR의 Operand에 저장된 주소를 PC가 가리키도록 한다. (0108 -> 0300)

5300 수행 과정


조건 분기 명령어 (vs 무조건 분기: JMP)

조건을 생성하여 비교하고 분기한다.

- 비교와 분기 작업을 하나로 융합한 명령어 구조도 존재한다.

- 비교 역시 산술, 논리 연산이고, 그 결과에 따라 분기가 결정된다.

 

연산 결과를 저장하는 플래그 레지스터가 존재한다. (0 or 1값 만을 갖기 때문에 비트라고도 불린다.)

= 상태 레지스터 = 조건 코드 레지스터

- 올림수(Carry): 연산 결과에 올림수가 있으면 1, 없으면 0

- 오버플로우(oVerflow): 연산 결과에 오버플로우가 있으면 1, 없으면 0

오버플로우: 컴퓨터가 표현할 수 있는 비트의 범위를 넘어가는 현상

- 부호(Sign), 음수(Negative): 연산 결과가 음수면 1, 양수 혹은 0이면 0

- (Zero): 연산 결과가 0이면 1, 0이 아니면 0

 

ex) X - Y 연산 결과가 0이면 1, 아니면 0을 반환하는 Z bit를 검사하여 1이 반환됐다면 114로 분기한다.

ex) R1과 R2를 비교하여 음수라면 1, 양수면 0을 반환하는 N bit를 검사하여 1이 반환됐다면 210로 분기한다.


프로시저의 호출/복귀 과정

CAL proc (가상 명령어)

proc:  프로시저 이름 (어셈블리 -> 기계어 과정 후 프로시저 시작주소로 변환)

 

인출 사이클: IR <- M[PC]; PC <- PC + x (x는 명령어 길이)

- 다른 명령어의 인출 사이클과 같다.

 

실행 사이클: TOS <- PC; PC <- proc

- TOS <- PC: 실행 사이클에서 복귀 후 수행할 명령어 주소(복귀 주소)를 TOS(Top Of Stack)에 저장한다.

- PC <- proc: 프로시저 시작 주소를 PC에 저장

- 복귀 주소를 저장 후 PC는 proc 시작 주소를 갖기 때문에 이후부터는 프로시저 proc의 명령어를 순차적으로 인출한다.

 

복귀 주소를 Stack이 아닌 그냥 register에 저장한다면?

=> 레지스터에 따로 복귀할 주소의 순서를 저장해야한다.

 

=> 따로 주소를 가리키지 않아도 TOS에 올라와있는 주소를 실행하면 된다.

RET (가상 명령어)

프로시저 종료 후 호출 프로그램으로 복귀한다.

 

인출 사이클: IR <- M[PC]; PC <- PC + x (x는 명령어 길이)

- 다른 명령어의 인출 사이클과 같다.

 

실행 사이클: PC <- TOS

- TOS의 내용 (복귀 주소)를 PC에 저장한다.

 

프로시저 호출/복귀 과정
프로시저 호출 복귀 시 스택