안 쓰던 블로그

컴퓨터 구조-분기 명령어, 서브루틴, 0/1/2/3주소 명령어 본문

컴퓨터 구조

컴퓨터 구조-분기 명령어, 서브루틴, 0/1/2/3주소 명령어

proqk 2020. 5. 30. 10:56
반응형

1. 분기 명령어

실행의 흐름을 변경하거나 어떤 루틴을 호출하는 데 사용한다

 

-BRZ X (Branch if Zero): 조건 코드가 0이면 X로 분기

-BR X: 무조건 X로 분기

-BRE R1, R2, X (Branch if equal): 레지스터 R1과 레지스터 R2의 내용이 같다면 X로 분기

-BRP X (Branch if Positive): 조건 코드가 양수면 X로 분기

-BRN X (Branch if Negative): 조건 코드가 음수면 X로 분기

-BRO X (Branch if Overflow): 오버플로우가 발생하면 X로 분기

 

 

 

 

 

 

2. 서브루틴의 호출과 복귀과정

서브루틴: 사용자에 의해서 메인 진행 중에 다른 코드 블럭에 가서 어떤 작업을 처리하고 오는 것, 인터럽트와 반대되는 개념(시스템이 강제로 처리)

 

1) 주 프로그램(main)이 CALL SUB1명령어를 만나서 서브루틴 SUB1실행(210번지->250번지)

2) SUB1 처리 중 CALL SUB2명령어를 만나서 서브루틴 SUB2실행(260번지->300번지)

3) SUB2에서 RET명령어 실행(호출한 명령어로 돌아가는 명령어) SUB1로 복귀(300번지->261번지)

4) SUB1에서 명령어 실행하다가 CALL SUB2를 만나면 다시 SUB2를 실행(280번지->300번지)

5) SUB2에서 RET만나면 다시 SUB1으로(서브루틴2에서->281번지)

6) SUB1에서 RET만나면 다시 주 프로그램 main으로

7) 주 프로그램에서 END만나면 프로그램 종료

 

이 과정 중에 CALL, RET같은 명령어가 실행될 때 스택이 사용된다

 

*스택: 후입선출 방식의 자료구조. 자세한 설명은 https://foxtrotin.tistory.com/171

*스택 포인터(SP): 스택에 데이터가 채워진 위치를 가리키는 레지스터. 스택 포인터가 가리키는 곳까지가 데이터가 있는 영역으로, 스택에 데이터가 삽입되거나 삭제되면 스택 포인터도 이동한다

 

 

서브루틴 수행과정에서 스택의 변화

1) SUB1이 호출된 후에 스택에 복귀할 주소 211을 저장

2) SUB2가 호출되면 스택에 복귀할 주소 261이 저장

3) SUB2가 종료되어 복귀하면 복귀하려고 저장해둔 주소 261을 삭제

4) SUB2가 호출되면 다시 복귀 주소 281 저장

5) 복귀하면 281삭제

6) SUB1 복귀하면 211삭제

 

 

3. 명령어 분류

오퍼랜드에 저장되는 데이터 형태

-주소 : 주기억장치의 주소나 레지스터의 주소

-수 : 정수, 고정-소수점 수, 부동-소수점 수

-문자 : ASCII 코드

-논리 데이터 : bit 혹은 flag

 

오퍼랜드가 주소를 나타내는 경우

오퍼랜드 수에 따라 0,1,2,3주소 방식이 존재한다

 

1) 0주소 명령어

연산 코드만 있고 주소를 지정하는 자료부(Operand)가 없는 명령어

PUSH X: 스택에 X를 삽입하고, 따로 저장하는 변수는 없다

 

Postfix방식으로 수식을 표현해야 한다(연산자를 피연산자의 뒷쪽에 표시하는 방법)

 

2) 1주소 명령어

오퍼랜드 한 개만 포함하는 명령어 형식, 오퍼랜드 형태는 주소

LOAD X: X번지 데이터를 누산기에 저장(AC<-M[X])

LOAD는 연산 코드, X가 기억장치 주소

 

3) 2주소 명령어

오퍼랜드 2개를 포함하는 명령어 형식, 오퍼랜드 2개 모두 주소를 저장하는 데 사용된다

MOV X, Y : Y번지의 기억장치 데이터를 X번지의 기억장치로 이동(M[X]<-M[Y])

 

4) 3주소 명령어

오퍼랜드 3개를 포함하는 명령어 형식, 레지스터의 주소를 저장한다

ADD X,Y,Z : Y와 Z번지의 데이터를 덧셈해서 X번지에 저장(M[X]<-M[Y]+M[Z])

X,Y,Z가 주소를 나타냄

 

 

4. 4가지 주소 형식 비교

 

X = B*(C+D*E-F/G)

다음 수식 연산을 4가지 명령어 형식에 맞춰 구현 후 비교해보자

 

-ADD : 덧셈

-SUB : 뺄셈

-MUL : 곱셈

-DIV : 나눗셈

-MOV : 데이터 이동

-LOAD : 기억장치로부터 데이터 적재

-STOR : 기억장치로 데이터 저장

 

1) 0주소 명령어를 사용한 프로그램

0주소 명령어에서는 STOR명령어가 없다

 

스택에서 위의 0주소 명령어 프로그램 동작 과정

1) B,C,D,E PUSH

2) E,D스택에서 POP한 뒤 E*D결과 PUSH

3) E*D결과와 C를 스택에서 POP한 뒤 E*D+C결과 PUSH

4) F,G PUSH

5) F,G POP하고 G/F결과 PUSH

6) F/G, C+E*D POP하고 C+E*D - F/G 결과 PUSH

11) C+E*D - F/G 결과, B POP하고, B*(C+D*E-F/G) 결과 PUSH

13) 최종 결과 POP해서 기억장치 X번지에 저장

 

 

2) 1주소 명령어를 사용한 프로그램

M[A}: 기억장치 A번지에 저장된 데이터 내용

T: 기억장치 내의 임시 저장 장소의 주소

 

1) F번지 데이터 누산기로 LOAD

2) 누산기 값을 G로 나눠서 누산기에 넣음

3) 누산기 값을 T번지에 저장

4) D번지 데이터를 누산기에 넣음

5) 누산기 값과 E번지에 있는 값 곱해서 누산기에 넣음

6) 누산기 값과 C번지에 있는 값 더해서 누산기에 넣음

7) 누산기 값과 T번지에 있는 값 빼서 누산기에 넣음

8) 누산기 값과 B번지에 있는 값 나눠서 누산기에 넣음

9) 누산기 값을 X번지에 저장

 

 

3) 2주소 명령어

R1, R2 : CPU 내에 위치한 레지스터

1) D번지 값을 레지스터 R1에 저장

2) R1의 값과 E번지의 값 곱해 R1에 저장

3) F번지의 값을 레지스터 R2에 저장

4) G번지의 값과 R2의 값을 나누어 R2에 저장

5) R2의 값과 R1의 값을 빼서 R1에 저장

6) C번지의 값과 R1의 값을 더해 R1에 저장

7) B번지의 값과 R1의 값을 곱해 R1에 저장

8) R1의 값을 X번지에 저장

 

 

4) 3주소 명령어

1) D번지 값*E번지 값 R1에 저장 

2) R1값+C번지 값 R1에 저장

3) F번지 값/G번지 값 R2에 저장

4) R값1-R2값을 R1에 저장

5) B번지 값*R1값을 X번지에 저장

 

 

명령어 주소 개수에 따른 장단점

주소 개수가 많은 경우

-저장할 오퍼랜드의 수가 많아지기 때문에 명령어가 더 복잡해짐

-레지스터 수가 많아져서 연산 속도가 빨라짐

-프로그램이 짧아져서 프로그램 당 명령어 수가 감소

 

주소 개수가 적은 경우

-오퍼랜드의 수가 적어서 간단하므로 명령어 인풀과 실행 속도가 높아짐

-프로그램의 길이가 증가한다.

 

 

[연습 문제]

1. R1이 10이고 R2가 20일 때 BRE R1, R2, 211이면 211로 분기되는가? (O/X)

더보기

X

BRE R1, R2, X (Branch if equal): 레지스터 R1과 레지스터 R2의 내용이 같다면 X로 분기

R1과 R2가 다르므로 분기하지 않는다

 

2. 그림에서 280번지 SUB2가 실행되면 스택에 어떤 값이 저장되는가?

더보기

281

280번지 명령어에서 서브루틴 후에 복귀할 주소가 스택에 저장

복귀는 그 다음 명령어 주소로 가기 때문에 281번지로

 

3. 그림에서 260번지의 CALL SUB2 명령어를 만나면 280번지로 JUMP한다(O/X)

더보기

X

SUB2로 JUMP하는 명령어니까 300번지로 JUMP한다

 

4. 다음 설명에 맞는 명령어 형식은?

오퍼랜드 3개를 포함하는 명령어 형식, 레지스터의 주소를 저장한다

더보기

3주소 명령어

레지스터 주소를 3개 저장하는 명령어 형식은 3주소 명령어이다

 

5. 기억장치 D번지 값과 E번지 값을 곱해서 R1 레지스터에 저장하는 명령어는?

더보기

MUL D, E, R1

 

반응형
Comments