일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- C++ 자료구조
- C 자료구조
- 필활
- 방탈출
- 홍대 방탈출
- 유니티
- 넥스트에디션 2호점
- 공포 방탈출
- 방탈출 추천
- 정렬 알고리즘
- 이스케이퍼스 2호점
- 홍대 방탈출 추천
- 꽃길
- 강남 방탈출
- PC VR
- 홍대 덤앤더머
- 방탈출 후기
- 2021 방탈출 추천
- 윈도우 프로그래밍
- 방탈출 리뷰
- Unity
- C#
- 추천
- 시스템 프로그래밍
- 홍대
- 이스케이퍼스
- 넥스트에디션
- 개발
- Android
- 후기
- Today
- Total
행복한 연어의 이야기
(윈도우 시스템) 4. 컴퓨터 구조 두번째 본문
1. 컴퓨터 구조의 접근방법
컴퓨터를 디자인 해보자
정확히는 CPU 를 디자인 해보자
CPU 의 기본 구성요소가 ALU, 컨트롤 유닛, 레지스터 임을 리는 알고 있다.
ALU와 컨트롤 유닛이 존재한다고 가정 하고 레지스터를 디자인 해보도록 하자
레지스터를 디자인 해보자
레지스터는 다음과 같은 내용으로 디자인한다.
1) 레지스터는 16 비트로 구성한다.
2) 레지스터 갯수는 기본적으로 8개로 구성한다. (r0 ~ r7)
3) 레지스터 8개 중에 4개는 용도를 미리 정해 둔다.
r4 = ir (Instruction Register)
r5 = sp (stack pointer)
r6 = lp (link register)
r7 = pc (program counter)
위의 구조는 ARM 코어 구조를 참조한 방식
명령어 구조 및 명령어를 디자인 해보자
CPU 에게 일을 시킬때는
'레지스터 r1 에 있는 값과 숫자 7을 더해서 레지스터 r2에 저장하라!'
라고 일을 시키게 된다.
레지스터를 16 비트로 구성했기 때문에 16비트 안에 저 내용을 다 담아 보자
명령어 | 2진 코드 | |
덧셈(ADD) | 000 | |
뺄셈(SUB) | 001 | |
곱셈(MUL) | 010 | |
나눗셈(DIV) | 011 |
명령어를 디자인한다.
레지스터 | 2진코드 |
r0 | 000 |
r1 | 001 |
r2 | 010 |
r3 | 011 |
r4 (ir) | 100 |
r5 (sp) | 101 |
r6 (lr) | 110 |
r7 (pc) | 111 |
레지스터를 구분한다.
일단 비워둠 | 연산자 | 저장소 | 피연산자1 | 피연산자2 | |||||||||||
레지스터를 필요한 내용들로 나눈다.
추가로 레지스터 인지 숫자인지 구분하기 위해서
피연산자 앞에 레지스터라면 1, 숫자라면 0 이라는 값을 넣어서 구현해보자
'레지스터 r1 에 있는 값과 숫자 7을 더해서 레지스터 r2에 저장하라!'
ADD | r2 | r1 | 7 | ||||||||||||
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
어셈블리 언어로 ADD r2 r1 7
바이너리 코드로 0000001010010111
이렇게 구현되었다.
2. Load & Store 명령어 디자인
Load & Store 명령어의 필요성
int a = 10; //주소값 0x10 가정
int b = 20; //주소값 0x20 가정
int c = 0; //주소값 0x30 가정
c = a + b;
우리가 만든 레지스터 명령어 구조로는 위의 내용을 실행할 수 없다.
메인 메모리에 저장된 a b 의 값을 불러올수도 c 로 저장할 수 있는 명령어가 없기 때문이다.
위의 계산을 진행하려면 int a 의 주소값인 0x10 에서 값을 읽어올 명령어와
int c 의 주소값인 0x30 에 값을 저장할 명령어가 더 필요하다.
Load & Store 명령어 디자인
명령어 | 2진 코드 | |
덧셈(ADD) | 000 | |
뺄셈(SUB) | 001 | |
곱셈(MUL) | 010 | |
나눗셈(DIV) | 011 | |
불러오기(LOAD) | 100 | |
저장하기(STORE) | 101 |
명령어를 추가한다.
일단 비워둠 | 연산자 | 레지스터 | 주소 값 | ||||||||||||
레지스터를 필요한 내용들로 나눈다.
컨트롤 유닛이 연산자를 읽고 나면 뒤에 오는 피연산자를 어떻게 읽을지 결정하게 된다.
연산자 내용에 따라( Load & Store 와 Add 등) 뒤 비트를 다르게 해석 한다.
이제 명령어를 만들었으니 위에 코드 내용대로 명령을 내려보도록 하자.
LOAD r0 0x10(a 의 주소값)
LOAD | r0 | 0x10 | |||||||||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
LOAD r1 0x20(b 의 주소값)
LOAD | r1 | 0x20 | |||||||||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
ADD r2 r0 r1
ADD | r2 | r0 | r1 | ||||||||||||
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
STORE r2 0x30(c 의 주소값)
STORE | r2 | 0x30 | |||||||||||||
0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
3. Direct 모드와 Indirect 모드
DIrect 모드의 문제점과 Indirect 모드
위 LOAD & STORE 에서 사용한 방법은 Direct 모드이다.
주소값을 명령어에 직접 표현하기 때문에 Direct 모드라고 한다.
Direct 모드의 경우 직접 표현할 수 있는 범위를 넘어가는 메모리 주소값을 가져올 수 없다는 단점이 있는데
이를 해결하기 위해서 Indirect 모드라는 것이 나왔다.
Indirect 모드 이해
예를 들어
주소값 0x10 에는 5 주소값 0x05 에는 3
이라는 값이 들어있다고 가정하고
Indirect 모드로 Load r1 0x10 명령을 내리게 되면
결과적으로 주소값 5(16진수로 0x05)가 가지고 있던 3의 값을 가져오게 된다.
반대로 Direct 모드로 Load r1 0x10 을 하게 되면 5의 값을 가져오게 된다.
또한 Direct 모드와 Indirect 모드를 구분하기 위해 비워두었던 비트를 사용하도록 하자.
Direct 모드 = 가르키는 값을 그대로 가져온다.
Indirect 모드 = 가르키는 값을 주소로 보고, 그 주소의 있는 값을 가져온다.
가정 : 주소값 0x10 에는 5 주소값 0x05 에는 3
Direct | LOAD | r1 | 0x10 | ||||||||||||
0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
r1 에 저장된 값 : 5
Indirect | LOAD | r1 | 0x10 | ||||||||||||
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
r1 에 저장된 값 : 3
알고 넘어가야할 것
1. 명령어 종류와 그에 따른 레지스터 변화
2. CPU 내부 연산과 레지스터 사용
3. Direct 모드와 Indirect 모드
'윤성우 저자'님의 '뇌를 자극하는 윈도우즈 시스템 프로그래밍' 책을 보고 정리한 내용입니다.
'IT > 윈도우 시스템 프로그래밍' 카테고리의 다른 글
(윈도우 시스템) 6. 커널오브젝트와 오브젝트 핸들 (0) | 2021.07.30 |
---|---|
(윈도우 시스템) 5. 프로세스 생성과 소멸 (0) | 2021.07.28 |
(윈도우 시스템) 3. 64비트 기반 프로그래밍 (0) | 2021.07.23 |
(윈도우 시스템) 2. 아스키코드 vs 유니코드 (0) | 2021.07.21 |
(윈도우 시스템) 1. 컴퓨터 구조 첫번째 (0) | 2021.07.19 |