728x90

소스 코드 파일을 여러개 만드는 이유

- 큰 프로그램을 하나의 코드로 만들 시 -> 복잡, 분량이 너무 큼 -> 작업 불가 -> 논리/기능 단위로 분리

- 라이브러리 활용 : 자주 쓰는 함수를 파일에 모아 여러 프로그램에서 같이 사용

- 소스 코드 + 라이브러리 소스 코드 전체 같이 컴파일은 비효율 적

 

외부 기호 참조 문법 - EXTERN 문법

- EXTERN symbol

- EXTERN 기호는 심벌 테이블에 등록, 외부에서 선언된 기호라 표시

- opcode에 임의의 값을 넣었다가 나중에 다른 파일에서 심벌 테이블을 읽어 대치함.

 

EXTERN 대치 시 주의 사항

- EXTERN 기호가 대치 시 다른 파일의 주소 값을 사용 x

- 모든 파일의 기계어 코드 + 변수 데이터가 결국 하나로 합쳐 바이너리 생성됨

- 코드/데이터 영역 크기 고려 필요

 

오브젝트 파일 Object file

- 모든 소스코드가 매번 컴파일은 비효율 -> 필요한 코드면 컴파일 + 변경 없는 코드는 컴파일 x

-> 변경 없는 파일을 미리 컴파일 해둠

<-> 미리 컴파일 시 변경된 코드와 병합 시 주소 영역 등이 일치 x

- 중간 파일 역활

 

오브젝트 파일로 바이너리 만들기

- opcode는 모두 기계어로 바꿈. 기호 정보는 오브젝트  파일에 기록

- 각 오브젝트 파일의 기호/참조 정보 조합 -> 바이너리 파일 생성

 

링커 Linker

- 오브젝트 파일을 합쳐 바이너리 만드는 프로그램

- 정적 링킹, 동적 링킹

 

링킹 Linking

- 오브젝트 파일 간 기호 참조 정보를 모아 분석, 정리

 

정적 링킹 static linking

- 라이브러리 오브젝트 파일과 프로그램 오브젝트 파일을 합쳐 단일 바이너리 파일 생성

- 링커 동작하기 간단

 

동적 링킹 dynamic linkiing

- 라이브러리 특정 영역을 필요한 순간 재배치하여 프로그램 동작 하는 방식

- 정적 링킹에 비해 바이너리가 작고, 컴파일 빠름

- 구현 어려움

 

오브젝트 형식 설계 시 주의 사항

- 기호 정보와 참조 정보를 어떻게 유지할 것가

- EXTERN은 외부 파일 참조 의미 -> 다른 파일에서 해당 값을 찾지 못할 수 있음 -> 링킹 실패

 

EXPORT 기호를 사용하는 방법 

- 외부에서 사용하는 기호에 EXPORT 선언 키워드 쓰기

- EXTERN은 타 파일 심벌 테이블에서 EXPORT만 찾아 링커 구성

- 오브젝트 파일에 EXPORT 기호만 포함시키므로 간단 <-> 불일치 시 에러 발생, 자유도 저하

 

EXTERN만 사용하는 방법

- EXTERN 만으로 외부 참조 기호를 찾을 수 있도록 링커 설계

- 다른 오브젝트 파일 심벌 테이블에 있는 모든 기호/참조 정보로 본체를 찾아야 함.

 

오브젝트 파일 형식

- 헤더 : 어디에 어떤 심블 테이블이 있는지 표시. 링커는 헤더의 기계어 시작부터 읽고 합쳐 바이너리 완성

- 내부 심벌 참조 테이블 : EXTERN 제외한 모든 기호의 심벌 테이블 정보. 심벌테이블을 오브젝트 파일에 기록한것.

   타 오브젝트 파일의 EXTERN이 참조하는 대상

- 외부 심벌 참조 테이블 : EXTERN 선언 기호 기록. 타 오브젝트 파일의 내부 심벌 참조 테이블에서 주소/값 읽어       

   opcode 인자에 씀

 

오브젝트 파일 형식

 

오브젝트 파일이 서로 참조하는 방법

- 한 오브젝트 파일의 외부 심벌 참조 테이블은 타 오브젝트 파일 내부 심벌 참조 테이블 참조

-> 링커는 모든 오브젝트 파일의 내부 심벌 참조 테이블로 통합 심벌 테이블을 만듬

-> 통합 심벌 테이블에서 각 오브젝트 파일의 외부 심벌 참조 테이블의 기호를 찾아 값/주소를 전달

 

오브젝트 파일 -> 바이너리

- 기계어 코드 : 코드 영역 + 데이터 영역이 위치한 곳

- 기계어 코드 내 심벌이 참조하는 opcode 인자를 심벌 테이블의 값/주소로 대치

-> 바이너리 완성

재배치 relocation

- 링커가 오브젝트 파일을 합칠 때 배치되는 순서

- 이 순서에 따라 기계어 코드에서 참조 주소 절댓값이 변경됨 -> 주소 값을 정해주는 작업

- 오브젝트 파일 = 재배치 가능 파일 형식

- 링커는 주소 절대 값이 바뀌어도 해당 주소 기호를 참조하도록 함

재배치 시 주소 지정 방식

- PC/Reg-PC 연관 주소 지정 방식을 제외한 모든 방식은 메모리 특정 위치를 절대값으로 주소 지정

- 절대 주소 지정 방식은 재배치로 기호/참조 정보의 주소가 바뀔 시 opcode의 주소 영역도 바뀌어야함.

- 연관(상대) 주소 지정 방식은 opcode 주소 영역 수정 필요 x

 

번역

- 코드의 체계가 바뀌는 과정

ex) 어셈블리어 -> opcode, opcode -> 기계어

 

컴파일 compile

- 상위 언어에서 하위 언어로 번역

- 최종 결과는 기계어

 

컴파일러 compiler

- 컴파일 하는 프로그램

 

빌드 build

- 컴파일 + 링킹해서 최종 프로그램을 만드는 전 과정

 

컴파일러 만들기

- 문법 정의가 필요

-> 대표적으로 BNF(backus-naur form) 베커스 나우어 형식

 

BNF

- 문법 체계가 있는 간단한 규칙 표현

 

BNF 예시

- ::= 은 프로그래밍 언어의 =처럼 우변을 좌변에 대입

- |은 또는

- <>는 확장

-> 문장에 대해 BNF로 아래처럼 정의

<문장> ::= <주어> <서술어>.
       | <주어> <목적어> <서술어> .
       | <문장> <접속사> <문장>.

 

BNF 정의 추가

- <>이 없는 경우 종결 기호

-> BNF 모든 규칙은 종결기호로 결과가 나옴

<주어> ::= <명사> <조사>
       | <명사>
      
<서술어> ::= <부사> <동사>
       | <동사>
      
<목적어> ::= <명사> <조사>
      
<명사> ::= 내 | 너 | 그
<동사> ::= 가다 | 오다
<부사> ::= 빨리 | 늦게
<조사> ::= 을 | 를 | 이 | 가
<접속사> ::= 그리고 | 그러나 | 그런데 | 하지만

 

BNF로 만들 수 있는 문장

내가 가다.
내가 오다.
너가 가다.
너가 오다.
그가 가다.
그가 오다.
내가 가다. 그리고 너가 오다. 그러나 그는 가다.

 

BNF 언어 설계

<program> ::= <block-list>
//프로그램은 하나의 블록 리스트

<block-list> ::= <ident>(<ident-list>) {<decl> <statement>}
              | <block-list> <ident> (<ident-list>) {<decl> <statement>}
/*
<ident> : 블록 이름
<decl> : 변수/상수 선언
<statement> : 연산/ 제어부분
*/

<ident-list> ::= <ident>
				| <ident-list>, <ident>

/*
ident-list 예시
       * ,를구분자로 사용
a, b, c, d, .., g
this_is_param
*/

<ident> ::= <ident> <ident-letter>
          | <ident> <digit>
          | <ident-letter>


/*
- ident의 예시
a
abbb
adasfwq53163
*/


<ident-letter> ::= a | b | c | ... | z | A | B | ... | Z
<digit> ::= 1 | 2 | 3 | ... | 9 | 0

<decl> ::= <def-decl> <var-decl>
		| <decl> <def_decl> <var-decl>

<def-decl>  ::= <ident> <number>

<var-decl> ::= <ident-list>;
		| <var-assignment-list>;
/*
  변수 선언부
<ident-list>; -> 변수명만 쓰고 ;로 끝냄
<var-assignment-list>; -> 변수명, 변수명, ... 변수명;
*/

<var-assignment-list> ::= <ident>=<number>
			| <var-assignment-list>, <ident>=<number>
/*
 변수 선언 문법
a=10
a=10, b=20, c=30
*/

<number> ::= <number> <digit>
// number : 십진수의 연속

<statement> ::= <ident>=<expression>	//a=3, c=a+b
            | <ident>(<ident-list>)		//func(), func(a, b, c, d, e)
            | (<statement-list>)
            | if <condition> then <statement>
            | while <condition> do <statement>

<statement-list> ::= <statement>
                  | <statement-list>; <statement>

<ident>=<expression>

<expression> ::= <term>
             | <adding-operator> <term>
             | <expression> <adding-operator> <term>

<adding-operator> ::= + | -

<term> ::= <factor>
        | <term> <multiplying-operator> <factor>

<multiplying-operator> ::= * | /

<factor> ::= <ident>
          | <number>
          | (<expression>)
          
<codition> ::= not <expression>
            | <expression> <relation> <expression>

<relation> ::= = | <> | < | > | <= | >= | ==


/*

if A > B then
C = A - B;
if A <= B then
C = B - A;
위 if문은 어셈블러어로 아래와 같이 컴파일 된다.
*/

if:
CMP A, B
BGT sub_a_b
BLET sub_b_a
sub_a_b:
SUB C, A, B
B end_if
sub_b_a:
SUB C, B, A
B end_if
end_if:
:

 빌드 과정

1. 컴파일러는 BNF 정의에 따라 소스코드 파싱(구문분석)

2. 최적화 된 어셈블리어로 번역 -> 고급언어의 결과 파일

3. 어셈블러가 오브젝트 파일로 변환

4. 링커가 오브젝트 파일 결합 -> 바이너리 완성

300x250
728x90

opcode의 한계

- opcode는 기계어와 1:1 대응 -> 모든 프로그램 작성 가능

- 프로그래밍 언어의 변수, 함수 같은 요소를 못써 과정이 매우 불편

 

어셈블리어

- Assembly language

- opcode보다 상위 프로그래밍 언어

- 어셈블리코드 -> opcode -> 기계어

 

어셈블리어의 추상화

- 추상화 정도가 낮은 경우 -> opcode와 유사 -> 기계어로 바로 번역

 

어셈블러

- asembler

- 에셈블리어를 기계어로 번역하는 프로그램

- 어셈블리어는 어셈블러에 종속됨 -> 에셈블러에 따라 문법이 다름

 

opcode와 어셈블러

- opcode는 cpu 제조사에서 정함 -> 특정 cpu의 opcode는 어셈블러와 상관없이 모두 똑같음.

- 어셈블러 개발사가 어셈블리 문법을 정함.

 

어셈블리어의 복잡도

- 문법의 정의에 따라 복잡 or 단순

- (추상화 수준을 낮춤) 단순 해질수록 opcode와 유사

- (추상화 수준을 높임) 복잡 해질수록 프로그래밍 언어에 가까워지며, 어셈블러 구현 힘듬

 

CPU 확장(데이터 버스를 16비트에서 32비트로)

- 접근 가능 메모리 용량이 32KB(2^16) -> 4GB(2^32)로 증가

- 여유 비트가 증가 -> 다양한 opcode 정의 가능

- 레지스터 확장 가능 : A, B, PC 3개 -> 16개(이 중 4개는 데이터 저장, 연산이 아닌 특수 용도)

 

레지스터 추가

- LR(Link register) : 하위 함수나 보조 루틴에서 작업을 마친 뒤 호출 위치로 복귀해야할때 호출 지점의 위치를 저장

- SP(Stack pointer) : 스택 레지스터 - 현재 사용하는 스택의 메모리 주소

- ST(Status) : 상태 레지스터 - ALU의 연산 결과를 저장하는 레지스터로 연산 결과와 같이 새 opcode에 사용

 

상테 레지스터(Status Register)

- 32비트 중 LSB 방향의 4비트만 사용

- 연산 결과가 32비트를 넘을 시 오버플로(overflow)에 1이 쓰임.

- 덧셈 or 곱셈 연산으로 자리넘김이 발생 시 캐리에 1을 씀.(ALU의 carry out 핀이 직접 연결됨)

- 연산 결과가 0일때 Zero에 1 써짐(ALU 출력 핀 전체가 연결된 32-input-NAND 게이트에 연결)

- 연산 결과가 음수일때 Negative에 1을 쓰기

특수 레지스터와 범용 레지스터

- 레지스터 16개 중 특수 목적의 LR, SP, ST, PC을 제외한 12개 레지스터는 데이터 처리용 

- 범용 레지스터의 이름은 A ~ L

 

어셈블리어 정의

- 이후 고급언어를 다룰것이므로 추상화 저수준 어셈블리어를 다룸

 

이동 명령

- MOV Rd, {Rs | Value}

- Rd : 데이터가 들어갈 레지스터

- Rs : 원본 데이터가 있는 레지스터

- Value : 그냥 값

- 이동 명령은 즉시 주소 지정 방식만 사용하므로 레지스터 이름이나 값을 직접 사용해야함.

*{A | B} 는 A나 B 둘중 하나를 선택

 

산술 명령

- 덧셈, 뺄셈, 곱셈, 나눗셈, 나머지 연산 5가지

- 주소 지정 방식을 어디까지 허용할 것인지 정해야 함

- ADD Rd, R1, {R2 | Value}

- SUB Rd, R1, {R2 | Value}

- MUL Rd, R1, {R2 | Value}

- DIV Rd, R1, {R2 | Value}

- MOD Rd, R1, {R2 | Value}

- 레지스터 끼리 or 레지스터와 값을 계산

- Rd는 값이 저장되는 레지스터

ex) ADD B, C, D => B = C + D

 

* 로드/스토어

로드 : SRAM -> 레지스터

스토어 : 레지스터 -> SRAM

 

로드/스토어 명령

- LDR Rd, { Rs | #Rs | [Rs] | [#RS] | Address | #Address | [Address] | [#Address] }

- STR Rd, { Rs | #Rs | [Rs] | [#RS] | Address | #Address | [Address] | [#Address] }

- 로드/스토어 명령에는 모든 주소 지정방식이 가능하도록 순서대로 지정

1. 레지스터 직접 주소 지정 방식

2. 레지스터-프로그램카운터 연관 직접주소지정방식

3. 레지스터 간접 주소지정방식

4. 레지스터-프로그램카운터 연관 간접주소지정방식

5. 단순 직접 주소 지정 방식

6. 프로그램 카운터 연관 직접 주소 지정방식

7. 단순 간접 주소 지정방식

8. 프로그램 카운터 연관 간접 주소 지정방식

 

로드/스토어 명령 예시

1. LDR A, [B] (레지스터 B에 0x2324가 저장 됨)

-> 주소 0x2324의 데이터를 읽어 레지스터 A에 저장

2. STR A, [B] (레지스터 B에 0x2000가 저장 시)

-> 레지스터 A의 값을 B의 값이 주소인 메모리(0x2000 번지)에 저장

 

논리 연산 명령

- AND Rd, R1, {R2 | Value}

- OR Rd, R1, {R2 | Value}

- XOR Rd, R1, {R2 | Value}

- Not Rd, {Rs | Value}

- 논리 연산은 즉시 주소 지정방식만 사용

- R1과 R2/Value을 연산하여 결과를 Rd에 저장

 

비트 시프트 명령

SHL Rd, R1, {Rc | Count}

SHR Rd, R1, {Rc | Count}

- 비트 시프트 명령도 즉시 주소 지정 방식만 사용

- R1의 데이터를 Rc 레지스터 혹은 count 만큼 왼쪽/오른쪽 시프트

 

* 이후 상태 레지스터를 사용하는 명령

 

비교 명령

- CMP R1, {R2 | Value}

- 연산 결과가 상태 레지스터에 저장 -> Rd, Rs 쓰지 않음

- CMP 명령으로 R1-R2가 0이 되거나 음수 인 경우 상태레지스터의 zero/negative 비트가 1이 됨

* SUB 명령 연산 결과에 따라 상태 레지스터는 변하지 않음

 

분기 명령의 종류

- BR { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BSUB { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BEQ { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BGT { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BLT { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BGET { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

- BLET { Reg | #Reg | [Reg] | [#Reg] | Address | #Address | [Address] | [#Address] }

 

분기 명령

- 분기 명령은 프로그램 카운터 레지스터의 값을 바꾸는 명령

 -> 주기억 장치 메모리 주소 만큼 데이터 처리가 필요

 -> 8개 주소 지정 방식 모두 사용

- BR : 조건 없는 분기. 해당 메모리 주소로 PC 값 변경

- BSUB : 분기 전 당시 PC 값을 링크 레지스터에 저장

 * 분기 명령은 함수 호출 등 구현에 자주 사용. 함수 처리 후 원래 위치 돌아갈때 그 원래 위치를 기억(링크 레지스터)

- BEQ : CMP 명령에서 R1, R2가 같을 때 분기 -> Status Reg : Zero bit 1 or Negative Bit 0

- BGT : R1이 R2보다 클때 분기 -> Status Reg : Zero bit 0 and Negative Bit 0

- BLT : R1이 R2보다 작을 때 분기 -> Status Reg : Zero bit 0 and Negative Bit 1

- BGET : R1이 R2보다 같거나 클때 분기 -> Status Reg : Zero bit 1 or Negative Bit 0

- BLET : R1이 R2보다 같거나 작을때 분기 -> Status Reg : Zero bit 1 or Negative Bit 1

 

 

*** 이전의 내용은 opcode 연관 어셈블리어 문법 ****

순수 어셈블리어 문법

- 상수 선언, 변수 선언, 레이블 정의 (분기 문법은 고급 언어에서 구현 예정)

 

상수 선언 문법

- 기호와 값을 정의 -> 어셈블리가 기호를 값으로 변경

- DEF symbol content

- content에 레지스터 이름, opcode, 다른 기호나 주소가 될 수 있음

 

변수 선언 문법

- BYTE symbol 초기값 : 1바이트 선언문

- WORD symbol 초기값: 4바이트 선언문

- STRING symbol "초기값" : 문자열 변수

- 상수 선언은 기호를 content로 변경, 변수 선언은 메모리 특정 위치에 변수 값이 저장

- 변수의 symbol이 변수 값이 저장된 메모리 주소 표현

 

레이블

- symbol:

- 어셈블러가 알아서 해당 위치 주소로 변경

 

어셈블러와 어셈블리어의 발전

1. (최초)기계어로 어셈블러 구현

2. 어셈블러로 어셈블리어 구현

3. 어셈블리어로 어셈블러 구현 ...

 

심벌 테이블(symbol table)

- 변수와 레이블 처리를 위해 어셈블러 수준에서 심벌 테이블을 만들어야 함.

 

심벌 테이블 만들기

- 어셈블리어 코드 한줄씩 읽기 -> 기계어로 변환

- 기호 정보(변수, 레이블) 만남 -> 기호 이름과 주소 오프셋 위치 심벌 테이블에 기록 -> 끝까지 읽어 심벌 테이블 완성

- 심벌 테이블의 참조 정보를 이용해 실제 값/주소로 대치하여 기계어 완성

 

심벌 테이블

- 기호 이름으로 구분 + 대치할 값이나 주소 등록

- 기호를 참조 위치 주소 오프셋은 ref에 기록

- 여러 번 참조 가능하므로 ref가 여려개 일수 있음

심벌 테이블 사용

- DEF symbol content -> content 값 자체로 대치

- [레이블] symbol : ->코드 영역 메모리 주소로 대치

 

메모리 영역 활용과 어셈블러

- BYTE, WORD, STRING으로 선언되는 변수는 메모리의 데이터 영역

- opcode가 어셈블러로 기계어로 번역되는 데이터는 메모리의 코드 영역으로 구분 필요

- 메모리에서 코드 영역과 데이터 영역을 어떻게 배치할 것인지 정책 필요.

 

메모리에 변수 영역 배치 방법

1. 변수 선언부에 두기

- 변수 선언부에 데이터 영역 배치

- 어셈블리어 코드 중간마다 변수 선언 시 코드 영역과 데이터 영역이 섞임 

 

2. 데이터 영역을 한 곳에 모으기

- 코드 영역의 앞이나 뒤 가능

- 코드 끝난 후 데이터 영역 배치시 중간 마다 변수 선언 되어도, 변수 선언 전에 참조되어도 상관 없음

- 변수 선언과 함께 심벌 테이블에 등록 순간에 실제 메모리 주소를 알 수 없다.

-> 코드 영역 번역 후 데이터 영역 할당 완료 후 심벌 테이블의 주소 공간 값 등록

어셈블러 동작

- 상수/변수 선언을 지나 코드 영역 만나면 opcode를 기계어로 번역

- 기호 참조시 심벌 테이블에서 해당 기도의 참조 위치 목록에 opcode의 프로그램 카운터 값을 넣음 

 -> 심벌 테이블 완성 후 참조 위치 목록 찾아 실제 값 넣음

 

two-pass 어셈블러

- 선언이 코드 보다 늦게 해석 -> 코드 해석시 심벌 테이블에 기호 정보가 없어 참조 위치 등록 불가

- 대부분 어셈블러는 두번 해석

- 첫 해석에서 코드는 무시하고, 데이터 정보만 해석하여 테이블 구성

 

two-pass 어셈블러 심벌 테이블 구성

1. opcode 건너 뛸때마다 어셈블러 내부 PC를 opcode 길이 만큼 늘림

2. opcode 건너 뛴 간격 만큼 데이터 영역 주소가 확정 -> 완전한 심벌 테이블

 

two-pass 어셈블러로 해석 예시

DEF   abc   50

BYTE  bbb  0xFF

 

MOV  A, abc

MOV  B, 0x33

 

ADD   C, A, B

STR    C, [bbb]

 

WORD nnn    0x10EF

 

LDR    A, [bbb]

CMP   A, C

BEQ    im_label2

 

im_label1:

LDR   D, #nnn

LDR   E, [#D]

CMP  D, E

SUB   F, D, E

BLET  im_label2

BGT   im_label1

 

im_label2:

SUB   F, E, D

SHR   G, F, 0x4

STR   G, [nnn]

STR   G, [#nnn]

 

첫 해석 후 심벌 테이블

two-pass 어셈블러 첫 해석

1. DEF abc는 값 50을 등록

2. 데이터 영역은 코드 영역 다음에 두므로 BYTE bbb의 주소로 0x44가 등록

3. nnn은 bbb 다음인 0x45로 주소가 등록

4. 레이블 im_label1/2는 코드 영역 주소 그대로 등록

5. 이후 주소, 갑, 해당 기호 참조 주소 기록 필요

* 주의) 명령어도 데이터 공간을 차지하므로 참조 주소의 값이 각 명령어의 시작 주소가 아님

 

심벌 테이블 완성하기

- 명령어는 32비트 -> 4바이트

- 명령어는 아래와 같이 분할되며 심벌 테이블에 참조 주소들이 등록됨

 

two-pass 어셈블러의 두 번째 해석

- 변수, 상수 등 기호 정보는 무시하고 기계어로 번역

- 기호 정보를 사용한 명령어를 만날시 심블 테이블에서 값/주소 찾아 사용

- 심벌 테이블에 없는 기호 사용 -> 에러 발생

어셈블러 처리 후 주소 배치

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

os만들기 - 1. 바이너리 에디터  (0) 2020.07.28
오브젝트 파일 ~ 고급 언어  (0) 2020.05.01
주소 지정방식  (0) 2020.04.29
Nand2Tetris 2 - 불 연산  (0) 2020.04.29
NAND2Tetris 1 - 불 논리  (0) 2020.04.25
728x90

폰 노이만 아키텍처에서 컴퓨터의 동작

- 데이터를 주기억장치에서 R/W 반복

-> 메모리 주소영역에 접근이 중요

but 아래의 회로에선 PC로 SRAM에 순차적으로만 접근 가능 -> 다른 주소 지정 방식 필요

폰 노이만 아키텍처 컴퓨터 회로

 

Opcode의 인자로 SRAM 주소 접근

- LDA 0x50(8비트 opcode 명령과 데이터)을 레지스터 말고 SRAM 주소에 저장

 * PC/SRAM 사이 Mux와 SRAM-레지스터 사이에 4출력 디먹스 사용

 

SRAM의 주소에 접근하기

- Demux(SRAM)에 sel0과 sel1이 둘다 0일때(NOR)

 -> Mux(PC)의 sel에 1 입력되도록 제어기 수정

 => PC가 가리키는 주소 뿐만이 아닌 SRAM에 임의(random) 접근 가능해짐 

 

접근 가능 주소 범위

- 현재 접근 가능 범위는 명령어 영역(8비트)+데이터 영역(8비트)이므로 0x00 ~ 0xFF까지만 가능

- 지금 SRAM은 64KB -> 전체 주소 영역이 0x0000 ~ 0xFFFF으로 전체 주소 접근 불가

 

주기억 장치 전체 주소 접근 방법

1. 데이터 접근의 지역성 이용 

2. 16비트 주소 값을 어드레스 디코더에 직접 입력

 

데이터 접근의 지역성

- 주로 접근하는 데이터는 실행 중인 메모리 위치 주변이 됨

- PC가 가리키는 곳의 근처 데이터를 자주 읽음

 

PC기준 8비트로 접근 가능 범위

- 8비트로 -128 ~ 127까지 가능

ex) PC가 0x3F20가리키는 경우

0x3F12, 0x3F16, 0x3F24, 0x3F28 ... 앞 뒤로 해당 범위 까지 접근가능

 

PC 중심으로 주소 값을 수정할 수 있는 회로

- SRAM DEMUX를 PC 16bit Adder 향해 입력 전달

- 8비트 이상 범위에 접근 불가

 

메모리 전체 주소 지정

- 현재 SRAM 회로 출력은 16비트이나 상위 8비트는 기계어로 사용되어

- 하위 8비트만으로 16비트 메모리 직접 지정이 불가

-> 16비트 출력 값이 모두 SRAM 디코더에 들어가도록 회로 변경이 필요

 => 8비트(기계어) + 8비트(데이터) or 16비트(주소 데이터)

 

제어기 확장

- (기존) 스위치 회로 -> (확장) 비교기 + 보조기억장치 + 8bit SRAM + 제어기 스위치 박스

- 동작

 1. 전원 연결시 보조 기억 장치의 데이터가 제어기 SRAM에 저장

 2. 주기억 장치에서 전달받은 상위 8비트 기계어는 비교기 거쳐 특정 값 출력

 3. 제어기 SRAM의 해당 주소에 저장된 값이 스위치 박스로 전달

 4. 컴퓨터 회로 제어

- 개선 : 스위치 회로를 복잡하게 구성할 필요가 없어짐 

메모리 주소 지정 이유

- 해당 메모리 값을 읽거나 쓰기 위함

 

즉시 주소 지정 방석(immediate addressing)

- 메모리의 주소를 지정하지 않음. 주로 레지스터에 값을 쓸 때 사용.

 

MOV

- move의 약어

- opcode : MOV 레지스터, 상수

- 상수 값을 레지스터에 저장한다.

- MOV A, 0x90 -> 레지스터 A에 0x90을 쓴다.

 

직접 주소 지정 방식(direct addresing)

- 1) PC에 8비트 값을 더하거나 빼서 메모리 주소를 구하거나

- 2) 직접 8비트 주소를 지정하는 방식 

 

단순 직접 주소 지정 방식(simple direct addressing)

- opcode의 인자로 사용한 값을 그대로 메모리 주소로 지정

프로그램 카운터 연관 직접 주소 지정 방식(PC relative direct addresing)

- PC 카운터에 opcode 인자를 더한 값을 주소로 지정

*로드, 스토어

로드 : 주기억장치에서 값을 읽어 레지스터에 저장

스토어 : 레지스터의 값을 주기억장치에 저장

 

opcode 추가

- LDR(Load register) : 레지스터에 값을 로드 

- STR(Store register) : 레지스터에서 값을 스토어

- 프로그램 카운터 연관 직접 주소 지정 방식 : #를 붙임

 

 예시

- LDR A, #0x34(현재 PC 값이 0x0046)

- 레지스터 A에 0x7A번지(0x0034 +0x0046) 데이터가 저장, PC는 0x0046유지

 

레지스터 직접 주소 지정 방식(register direct addressing)

- 레지스터 출력 값을 SRAM 주소로 전달되는 방식

- 레지스터 크기가 16비트로 SRAM의 주소 크기와 같으므로 전체 영역에 주소 지정 가능

- 레지스터에 미리 주소값을 넣어두어야 함.

 

예시

- MOV B, 0x34

- LDR A, B

 

레지스터-프로그램 카운터 연관 주소 지정방식(Register PC relative direct addressing)

- 레지스터와 PC값을 더해서 SRAM 주소 지정

-> PC 중심으로 전체 메모리 영역 접근 가능

 

간접 주소 지정 방식

- 주소 지정을 간접적으로 하는 방식

- 직접 주소 지정 방식으로 메모리에 주소 지정. 그 주소에서 출력된 SRAM 값을 주소로 다시 지정

 

전체 회로도

- 스위치에서 주소 지정 방식 처리가능한 CPU 회로

- 하드웨어를 제어하기 위해 기계어가 나오고 더 편하게 쓰기 위해 opcode가 나옴

 

 

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

오브젝트 파일 ~ 고급 언어  (0) 2020.05.01
어셈블리어 ~ 심벌 테이블  (0) 2020.05.01
Nand2Tetris 2 - 불 연산  (0) 2020.04.29
NAND2Tetris 1 - 불 논리  (0) 2020.04.25
NAND2Tetris 0 - 소개  (0) 2020.04.25
728x90

제어기

- 컴퓨터회로의 멀티플렉서, 디멀티플렉서, ALU의 ADD/SUB 등 제어가 필요한 부분들이 존재

- 한 곳으로 모은 제어기를 만듬

 

제어기 스위치

- 제어기 스위치를 제어하여 로드/스토어 작업 수행

제어 예시

- PC가 가리키는 SRAM 값을 레지스터 A에 저장

  - SRAM MUX SEL : 0 0[보조 기억장치 선택]

  - SRAM DEMUX SEL : 0 0 [레지스터 A 방향 선택]

  - Reg A MUX SEL : 1[SRAM 방향 선택]

  - SRAM RW : 1[읽기 모드]

  - MUL/DIV : 0[상관 x]

  - SUB/ADD : 0[상관 x]

-> 레지스터 A에 값을 저장 = 00001100 = 0x0C

 

 

MUX/DIV와 SUB/ADD 조합에 따른 ALU의 연산

* 덧셈 : 0(MUL/DIV), 0(SUB/ADD)

* 뺼셈 : 0(MUL/DIV), 1(SUB/ADD)

* 곱셈 : 1(MUL/DIV), 0(SUB/ADD)

* 나눗셈 : 1(MUL/DIV), 1(SUB/ADD)

 

기계어

- 컴퓨터 회로의 제어기를 제어하는 2진수 언어

 

위 컴퓨터 회로 기계어 정리

메모리에서 기계어 받는 제어기

- 기계어를 보조 기억 장치로 부터 받을 수 있음

- 코드램 : 제어기 쪽에 연결된 SRAM

- 데이터램 : ALU쪽에 연결된 기존 SRAM

 

 

보조기억장치로부터 기계어를 받는경우/ 데이터를 받는 경우

- 기계어를 데이터램에 입력하지 않도록 해야함

 -> 클록 펄스를 구분해서 입력

- 코드 램에 데이터 입력시 -> 데이터 램의 CLK에 펄스 X 코드램의 CLK 펄스 O

- 데이터 램에 데이터 입력시 -> 데이터 램의 CLK에 펄스 O 코드램의 CLK에 펄스 X

 

컴퓨터 회로 총 정리

데이터의 저장

- 메모리의 하위주소에서 상위주소로 저장

 

리틀 엔디언

- 하위 바이트 부터 저장

 

빅 엔디언

- 상위 바이트 부터 저장

 

컴퓨터가 처리하는 데이터

- 처리 데이터 = 동작 명령어, 계산 데이터

 

하버드 아키텍처

- 명령어(8비트) -> 코드 램에 저장, 데이터(8비트) -> 데이터 램에 저장

=> 분리된 메모리 저장하는 방식

폰 노이만 아키텍처

- 명령어(8)와 데이터(8)를 합쳐(16비트) 같은 메모리에 저장하는 방식

- 메모리는 16비트 데이터를 출력함

- 상위 8비트는 제어기, 하위 8비트는 ALU로 전달

 

하버드 아키텍처와 폰 노이만 아키텍처

- 하버드 아키텍처는 메모리가 분리되어 데이터 입출력과 명령어 처리 동시 수행 가능 -> 빠른 속도

 <-> 메모리가 분리되고 별개의 어드레스 디코더 제어로 회로가 복잡 => 고비용

- 폰 노이만 아키텍처는 램을 하나로 줄였지만 동작방식은 하버드 아키텍처와 비슷

 

16비트 CPU

- 데이터를 16비트 씩 처리 -> 2바이트씩 SRAM 주소를 이동해야함

=> 프로그램 카운터를 2씩 늘려줌

2씩 늘어나는 PC

 

8비트, 16비트, 32비트, 64비트 CPU 구분 기준

- 데이터 버스 폭과 ALU의 데이터 처리 크기

 

 

16비트 CPU 구조

 

OPCODE

- LDA = Load to A

- STA = Store from A

 

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

NAND2Tetris 1 - 불 논리  (0) 2020.04.25
NAND2Tetris 0 - 소개  (0) 2020.04.25
ALU~보조기억장치  (0) 2020.04.24
가산기~주기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
728x90

가산기의 뻴셈 연산

- 2의 보수를 이용하여 가산기 만으로 뻴셈이 가능

- 덧/뻴셈 선택하는 신호선을 만들고 원래 수 그대로 입력하도록 회로 수정 필요

 

XOR 게이트를 이용한 4비트 2진수 1의 보수 변환

- 12 - 8 시 XOR 게이트를 이용하여 1의 보수로 변환 가능

= 1100 - 0100

= 1100 + 0100의 1의 보수 + 1

 

뼬셈 가능한 8비트 가산기 회로

- SUB/ADD 입력에 따라 0인경우 덧셈, 1인경우 뻴셈하도록 XOR를 이용해 1의 보수 변환

- 2의 보수 변환은 Cin에 SUB/ADD(1)을 전달하여 +1을  수행

산술 논리 연산 장치

- 연산기(논리 연산 장치) : 이전의 덧/뻴셈 연산이 가능한 회로

- ALU(arithmetic logic unit) : 산술 논리 연산 장치. 덧/뺄/곱/나눗셈 수행

 

곱셈 회로

- 소프트웨어적으로 구현 가능하나 디지털 회로로 구현한 것 보다 느림

 

10진수의 곱셈

 

2진수의 곱셈

- 각 비트의 곱셈은 AND 게이트로 구현

4비트 이진수 x 4비트 이진수 곱셈기

나눗셈기

1비트 비교기 회로

 

ALU

= 가산기 + 감산기 + 곱셈기 + 나눗셈기

 

보조기억장치

- 앞서 휘발성인 SRAM 주기억장치와, D-FF 메모리 레지스터를 사용

- 전원이 없어도 데이터가 소멸되지 않는 보조기억장치가 필요

 

천공카드

- 구멍을 뚫어 데이터를 저장하는 종이

- 뚫리면 1, 뚫리지 않으면 0

 

천공카드 리더기(punched card reader)

- 읽기 쓰위치를 닫으면 전자석 동작

- 천공 카드 아래의 접점을 끌어당김 

- 구멍이 뚫린 부분만 접점이 통과하여 연결됨

=> 아래의 경우 00100010(2) -> 34(10)

천공카드를 읽어 연산하는 디지털 회로

- 이전의 입력 스위치 8개 대신 8비트 천공 카드 리더기를 입력으로 받음

- 천공 카드 데이터를 입력 받아 연산할 수 있으나 쓰기는 하지 못함

SRAM 데이터를 천공카드에 저장하는 회로

- SRAM 아래의 DEMUX를 1입력3출력 DEMUX로 변경

- 추가 된 출력을 천공카드 리더기의 입력으로 연결

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

NAND2Tetris 0 - 소개  (0) 2020.04.25
기계어~OPCODE  (0) 2020.04.25
가산기~주기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
인버터~플립플롭  (0) 2020.04.23
728x90

반가산기

- 2진수 1비트 덧셈 연산하는 회로

- 자리 올림을 입력 받지 않아 반쪽짜리 가산기란 의미

전 가산기

- Full Adder

- 자리올림을 포함한 전체 덧셈 회로

- 전 가산기 = 반가산기 2개 + OR 게이트

4 비트 가산기

- 전가산기 4개를 이어 만듬

 A3210  B3210

- 0011 + 1011

    A  B  C

 1. 1+1+0(C) = 0(S)/1(C)

 2. 1+1+1(C) = 1(S)/1(C)

 3. 0+0+1(C) = 1(S)/0(C)

 4. 0+1+0(C) = 1(S)/0(C)

=> 0011 + 1011 = 1110

 

8비트 가산기 기호

 

기억장치와 가산기의 연결

- 가산기를 사용 후 결과를 기억할 수 없음 -> 기억장치와 가산기를 연결

1. 8비트 가산기 입력으로 D 플립플롭 램 연결

2. 램 위에 스위치 연결

3. 입력 A의 플립플롭 위에 멀티플랙서 MUX 추가 -> 스위치 or 가산기 결과 둘 중하나를 선택해서 보냄

2-입력-1-출력-멀티플렉서

- 멀티플렉서(Multiplexor:MUX) : 2개의 입력 신호 중 1개를 선택해서 출력

 

가산기의 계산

- 10 + 4+ 18 + 21 + 36 + 37 + 5의 계산

- 10(A), 4, 18, ..., 5는 입력 B를 통해서 입력

 

1. 처음에는 스위치 A와 스위치 B로 입력

2. 가산기의 계산 결과가 입력 A로 다시 들어감

 가산기 + 기억 장치의 계산 흐름

레지스터

- 연산 장치의 값을 저장하기 위한 작은 메모리

- 중간에 레지스터가 없는 경우 가산기 출력 동시에 바로 입력이되어 잘못된 계산 수행 가능하여 이를 방지

- 레지스터는 플립플롭/SRAM/DRAM 중 가장 빠른 플립플롭으로 만듬

 

2진수의 음수 표현

- MSB를 부호 비트(sign bit)로 사용

- 0110100 : MSB가 0이므로 양수, 0110100(2) = +52(10)

- 1110100 : MSB가 1이므로 음수, 1110100(2) = -52(10)

 

2진수의 뺄셈

- 2진수의 뺄셈 = 2진수 + 2진수의 2의 보수

- 1111 - 0010 = 1101

- 1111 + 1110(0010의 2의 보수) =  1101

=> 뺼셈을 덧셈으로 구현 가능

 

전자석 -> 릴레이 -> 인버터 -> (+피드백 연결) -> 오실레이터 (클럭)

게이트 : 트랜지스터 -> 논리 게이트

기억 장치 : R-S 래치 -> R-S 플립플롭 -> J-K 플립플롭 -> D 플립플롭 -> 1바이트 램 -> 8 바이트 램

              -> 8바이트 플립플롭 램 + 어드레스 디코더 + 쓰기 스위치 + 읽기 버퍼/SRAM/DRAM

연산 장치 : 반 가산기 -> 전 가산기 -> 8비트 가산기

 

 

프로그램 카운터+주기억 장치가 추가 된 회로

- 가산기 + 레지스터 회로는 일일이 계산할 값과 CLK를 넣어야 계산 됨

- 10, 4, 18, 21, 36, 37을 한번에 입력한 후 디지털 회로가 알아서 계산하도록 자동화

-> 프로그램 카운터 + 주기억 장치 추가

 

DEMUX

- demultiplexor)의 약어

- 멀티 플렉서의 반대 동작. 하나의 입력을 여러 곳 중 하나로 출력

 

주기억장치 64KB SRAM

- 64KB 크기 -> 0x0000 ~ 0xFFFF 범위 -> 2^10(키로바이트) * 2^6(64)

  -> 2^16 이므로 어드레스 디코더는 16비트 주소 핀 필요 

- 1바이트(8비트) 입력과 1바이트(8비트) 출력

 

프로그램 카운터

- Program Counter(PC)

- 명령어의 위치(주기억 장치 메모리 주소)를 가리킴

 -> 주기억 장치의 어드레스 디코더와 연결

- 아직 명령어 개념 설명 전이므로 8비트 가산기 계산 결과 값이 저장되는 위치를 가리킴

- 카운터는 1씩 증가 -> 다음 주소를 가리키기위해서

 

프로그램 카운터 전용 16비트 가산기

- CLK가 한번 입력 될때마다 프로그램 카운터 출력 값을 1씩 증가

 

주기억 장치로 PC 입력하기

- 1 + 9 + 10 + 12 + 21 + 40 + 37 연산

1. 위 7개 수를 주기억 장치에 입력 

 - R/W : 0(쓰기 모드)

 - 스위치 8개로 8비트 2진수로 입력

 - 각 수를 입력 할때마다 SRAM, PC에 CLK 입력

 => 7개의 수가 0x0000 ~ 0x0006 까지 SRAM에 저장

2. PC의 CLR 신호에 1을 주어 PC 카운터 저장 값을 0으로 바꿈

 -> PC가 가리키는 주소는 한칸씩 내려감

3. 0x0000을 레지스터 A에 입력하기

 - 2번 단계서 프로그램 카운터 값을 0으로 바꿈 -> 0x0000이 SRAM에 전달

 - R/W에 1로 읽기 상태 + 0x0000(Address Decoder) -> 해당 주소 값이 출력

 - DEMUX의 SEL을 0으로 -> SRAM 출력은 A로 간다 -> 레지스터 A 위 MUX를 SEL 1하여 레지스터 A로 입력시킴

4. 0x0001을 B에 입력하기

 - PC의 CLK가 입력되어 PC가 1 증가

 - ADDRESS DECODER는 0x0001번지 읽음

 - DEMUX SEL을 1로 지정하여 레지스터 B로 전달

 

5. 0x0006까지 연산

 - 레지스터 값을 A+B 연산 후 레지스터 A의 먹스 SEL 0으로 설정하면 연산 결과를 레지스터 A에 저장

 - PC 카운터가 1씩 증가하여 0x0000 ~ 0x0006 까지 값이 출력되며 덧셈 연산

 => 연산 종료 시 PC의 값은 7이 됨.

6. 계산 결과를 다시 주기억 장치에 저장하기

- 0x0007의 값이 레지스터 A에 남음 -> SRAM에다 저장 필요

- SRAM 위에 3입력 MUX 추가하여 레지스터 A와 B의 출력 + 8개 스위치를 받도록 연결

- 3입력 먹스 : 스위치 입력 (0,0), 레지스터 A 출력 (1, 0), 레지스터 B 출력 (0, 1)

- PC가 7을 가리킬 때, SEL0[1], SEL1[0]으로 하여 레지스터 A 값을 SRAM으로 전달

- SRAM의 R/W를 0으로 하여 쓰기 모드시 0x0007에 연산 결과를 저장

로드와 스토어

- 로드 : 주기억 장치 값을 읽어 레지스터 A,B에 옮김

- 스토어 : 레지스터 값을 주기억 장치에 저장

=> 컴퓨터 작업은 로드와 스토어들의 연산

 * 그레픽 카드를 제어하는 주소에 스토어 시 모니터에 그림, 글씨 출력

 * 사운드 카드 제어하는 주소에 스토어 시 소리가 출력

 => 데이터를 스토어하는 위치에 따라 출력 형식이 바뀜

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

기계어~OPCODE  (0) 2020.04.25
ALU~보조기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
인버터~플립플롭  (0) 2020.04.23
디지털 ~ 릴레이  (0) 2020.04.23
728x90

D 플립플롭

- R-S 래치에 인버터를 추가하여 같은 값이 입력 되지 않게 고친 플립플롭

메모리 셀

- 1비트 래치/플립플롭

 

램(RAM)

- 플립플롭을 이어 만든 것

- SRAM : 트랜지스터로 만든 래치 모음

- DRAM : 캐패시터와 트랜지스터를 이어 만든 것

 

D 플립플롭 1바이트 램

- 입력 CLK를 스위치 1개를 연결하여 워드라인(Word Line : WL)이라 하고

- 입력 D에 연결한 스위치 8개를 입력이라 한다.

=> 1바이트를 1워드로 묶어 일괄적으로 클록 공금

=> 0 ~ 255까지 입력 가능

 

 

1바이트 램에 이진수 10000110 저장 순서

 

 

MSB와 LSB

- 디지털 회로에서 1비트 이상 데이터 처리시 어느 신호선이 높은 자리인지 낮은자리인지 정해야 함

- MSB(Most Significant Bit) : 가장 높은 비트 위치

- LSB(Least Significant Bit) : 가장 낮은 비트 위치

=> 10000110에서 LSB는 오른쪽 끝 0, MSB는 왼쪽 끝 1

 

 

 

 

 

 

 

메모리 주소

- 1바이트 크기 램에 데이터를 쓰기 위해 8개 스위치 사용, 2바이트의 경우 스위치 16개, 출력 16개 필요

- 1KB 램의 경우 8192개(2^13) 스위치 필요 -> 1MB는 스위치 100만개 필요 => 불가능

<->

램의 특정 주소에 데이터를 쓰거나 읽기

1. 램 영역을 1바이트로로 나누고 주소 지정

2. 그 주소를 찾아 해당 주소의 메모리 셀이 동작

 

1KB 램의 메모리 주소

- 8,192개의 메모리 셀을 8개로 묶음 -> 1바이트 씩 주소 할당 -> 0 ~ 1023까지 주소 사용 가능

 

D 플립플롭 메모리 셀 회로

- D 플립플롭 회로에 입출력, 셀 선텍, 읽기/쓰기 동작 선택 단자를 추가 한 회로

- SEL에 0이면 값 저장 상태 유지

- SEL이 1이면 읽기/쓰기 동작

  - RW : 0 -> 저장된 값 출력

  - RW : 1 -> 입력된 값 저장

메모리 셀 기호


8바이트 램 구성

- 메모리 셀이 가로 8개 세로 8개 총 64개 구성

- 주소는 0 ~ 7까지. 이진법으로 표현 시 3바이트 필요 -> 어드레스 디코더 입력(a1, a2, a3)이 3개

- 주소 신호선은 각 메모리 셀 선택 단자에 연결

- 1바이트 표현에 8개의 입출력 필요 -> 입력 스위치 8개/ 읽기 버퍼 8개

* DI(data input), DO(data output)

어드레스 디코더

- 램 주소를 지정할때 입력 스위치 갯수를 줄이기 위해 사용

- 현재 주소가 7개 뿐이므로 출력 7개(0 ~ 7), 입력 3개(2^3) 총 10개의 스위치로 주소 지정 가능

- 이 경우 3-입력-8-출력 디코더

 

8바이트 램 0x2번지에 6쓰기

- 6은 0000 0110

DI  0 1 2 3 4 5 6 7

->  0 1 1 0 0 0 0 0

 

8바이트 램 0x2번지 값 출력(읽기)

플립플롭 메모리

- SRAM이나 DRAM 처럼 대용량 주기억장치로 쓰기에는 크고 복잡

-> CPU 내부 레지스터에 사용

 

SRAM, DRAM

- SRAM : 트랜지스터로 래치 만듬

- DRAM : 캐패시터로 만듬

 

휘발성 메모리

- D 플립플롭, SRAM, DRAM

- 크기가 큰 순 : D 플립플롭 > SRAM > DRAM

- DRAM은 캐패시터를 사용하여 D 플립플롭이나 SRAM보다 느리고 전력 소모가 큼 -> 대용량 주기억 장치로 사용

- SRAM -> 캐시 매모리

- D 플립플롭 -> 레지스터

 

전자석 -> 릴레이 -> 인버터 -> (+피드백 연결) -> 오실레이터

트랜지스터 -> 논리 게이트 -> R-S 래치 -> R-S 플립플롭 -> J-K 플립플롭

-> 1바이트 램 -> 8 바이트 램 -> 8바이트 플립플롭 램 + 어드레스 디코더 + 쓰기 스위치 + 읽기 버퍼/SRAM/DRAM

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

ALU~보조기억장치  (0) 2020.04.24
가산기~주기억장치  (0) 2020.04.24
인버터~플립플롭  (0) 2020.04.23
디지털 ~ 릴레이  (0) 2020.04.23
CPU 추가  (0) 2020.04.20
728x90

전자석으로 불끄는 회로

- 입력이 0이면 출력이 1

- 입력이 1이면 출력이 0

=> 인버터

 

인버터

- 입력과 출력을 반대로 해주는 회로

피드백 회로

- 인버터의 출력이 다시 입력으로 들어감

ex) 출력이 0 -> 입력 0 -> 출력 1 -> 입력 0 -> 출력 1

 

인버터-피드백 회로의 출력 그래프

- 0과 1의 규칙적인 반복

=> 클록 신호

 

오실레이터

- 특정 속도로 클록 신호를 발생시키는 장치

- 크리스털로 만듬

-> 온습도 등 외부 요인에 영향을 적게 받으면서 규칙적인 진동을 내기 때문

- 모든 디지털 장비에는 크리스털 오실레이터가 사용됨

* 디지털 회로에서 오실레이터는 사람의 심장과 같은 역활

* 모든 디지털 장치는 오실레이터의 클록 신호를 기반으로 동작

 

전자석 -> 릴레이 -> 인버터 -> (+피드백 연결) -> 오실레이터

 

릴레이와 트랜지스터

- 릴레이와 npn형 트랜지스터는 똑같이 동작

=> 트랜지스터는 릴레이의 반도체 버전

+ 트랜지스터로 논리 연산가능

AND 게이트

 

OR 게이트

NAND 게이트

 

전자석 -> 릴레이 -> 인버터 -> (+피드백 연결) -> 오실레이터

트랜지스터 -> 논리 게이트

 

R-S 래치

- R(Reset), S(Set)

- Latch : 잠금

=> 논리게이트와 피드백 회로로 회로에 전류가 걸림 -> 데이터 저장

- R-S 래치는 1비트 값 저장하는 디지털 회로

 

R-S 플립 플롭

- R-S 래치는 출력으로 Q와 Q바의 값이 항상 반대여야 함

-> Q와 Q바가 동시에  0이 되는 입력 R, S가 (1,1) 되면 안됨

=> 2개의 AND 게이트 + CLK 신호 사용 => R-S 플립플롭

* R-S 래치를 간략히 추상화하여 표시

R-S 플립 플롭의 진리표

- 입력 R과 S를 전환 할 때 (1,1)이 될 위험이 큼

-> R-S 플립플롭에서 CLK가 0일때만 R-S 신호를 바꾸도록 하면 해결

J-K 플립플롭

- R-S 플립플롭에서 여전히 허용되지 않는 입력 값 상태가 존재

-> 3-입력 AND게이트 활용하여 해결 => J-K 플립플롭

J-K 플립플롭의 진리표와 타이밍 다이어그램

라이징 에지와 폴링 에지

- 오실레이터의 클록 출력은 0과 반복

- 라이징 에지 : 0에서 1로 바뀌는 순간

- 폴링 에지 : 1에서 0으로 바뀌는 순간

 

전자석 -> 릴레이 -> 인버터 -> (+피드백 연결) -> 오실레이터

트랜지스터 -> 논리 게이트 -> R-S 래치 -> R-S 플립플롭 -> J-K 플립플롭

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

가산기~주기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
디지털 ~ 릴레이  (0) 2020.04.23
CPU 추가  (0) 2020.04.20
CPU - CPU개요, 디지털 연산  (0) 2020.04.19
728x90

전체 흐름

 

1. 디지털 - 0, 1과 같은 이분법 체계

2. 이진수로 글자 표현 = 코드

3. 증폭기(트랜지스터) <- 릴레이 <- 먼 거리 전송의 어려움

4. 오실레이터 <- 피드백 회로

5. 논리 게이트 <- 트랜지스터 + 피드백

6. 메모리 <- 플립 플롭 <- 게이트 + 피드백

7. ALU <- 가산기, 뺄셈기, 곱셈기, 나눗셈기 <- 논리 게이트

8. 기계어 <- 제어기 <- CPU = ALU + 레지스터

9. 고급 언어<- 어셈블리어 <- 기계어

 

디지털

- 0(LOW), 1(HIGH)

 

디지털 회로

- 디지털 신호를 사용하는 회로

 

5V 디지털 회로

- 0~1.5V를 0

- 3.5 ~5V를 1

 

간단한 전등 회로

- 전지, 스위치, 전등 구성

- LOW에서 HIGH나 역으로 바뀔때 서서히 변화(실제로는 빠름)

 

코드

 

전등으로 통신하기

- 서로 규칙을 정한 만큼 깜빡임

- wow! 하려고 125번 깜빡이기는 어려움 -> 코드

코드

- 수와 문자를 1:1 연결

 

아스키 코드

- 7비트 인코딩

-> 33개의 출력 불가능한 제어 문자 + 95개의 출력 가능 문자 총 128개

 

코드의 출력

- 아스키 코드 'b'는 십진수로 90

-> 90번 깜빡이긴 힘들다

-> BSD 코드를 사용해 2진수로 표현

 

10진수 2진수 변환

 

BCD 코드

- Binary Coded Decimal

- 2진화 10진 코드(8421코드)

문자 'u' 보내기

- 문자 'u'은 아스키 코드 85

-> 스위치로 0100 0101 보내면 된다.

 

비트

- 이 진수 1자리

 

바이트

- 8자리 2진수

 

데이터

- 비트나 바이트 묶음

 

디지털 데이터 통신

- 디지털 신호로 데이터 전달

 

먼 거리 통신의 문제

- 거리가 멀 수록 저항 상승, 전압은 그대로이므로 전류가 줄어듬(V=IR)

-> 전류 증폭 필요

 

전자석

- 쇠못에 구리 코일 감아 양 끝을 전지로 연결한 것

 

전자석으로 옆 회로 불켜기

- 스위치 A 닫음

-> 전자석 동작 -> 스위치 B가 끌려와 닫김

-> 불 켜짐

=> 릴레이 원리

 

 

릴레이

- 이어달리기에서 유래

- 전자석을 이용한 스위치 회로

 

릴레이로 신호 증폭과 데이터 전달

- 먼거리 통신하는 전자회로 완성

-> 사람의 개입이 필요

-> 이후 전자회로 자동화

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

가산기~주기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
인버터~플립플롭  (0) 2020.04.23
CPU 추가  (0) 2020.04.20
CPU - CPU개요, 디지털 연산  (0) 2020.04.19
728x90

메모리  구조

- 어드레스와 명령/데이터

 

버스

- 어원은 합승 버스(Omnibus)

- 데이터의 통로를 의미함. <- 신호 선을 다발로 묶은 것

- 어드레스 버스 : 주소 전달하는 버스

- 데이터 버스 : 데이터 전달

- 외부 버스 : CPU와 외부 장치를 연결

- 내부 버스 : CPU 내부의 데이터를 전달하는 버스

 

버스와 비트 수

- 버스는 신호 선을 다발로 묶은 것으로 신호 선의 수 = 비트 수

- 64bit CPU는 64 비트의 처리폭을 가진 CPU

 

어드레스 버스 폭

- 어드레스 공간의 크기

- 32비트 라면 4.3G의 어드레스가 있음.

 

명령

- 오퍼랜드와 명령 코드로 구성

- 오퍼랜드 : 연산의 대상

- 명령 : 덧셈, 저장 등

 

레지스터

- CPU 내부의 기억장치

- 어커뮬레이터(누산기) : 계산 결과를 누적

- 범용 레지스터 : 계산 이외 사용

- 명령 레지스터 : 명령(프로그램)을 저장

- 프로그램 카운터 : 다음 실행할 명령의 어드레스를 저장

 

클록

- 일정 주기로 H와 L을 반복하는 신호.

- ALU에서 데이터를 래치하거나 프로그램 카운터를 진행시키는데 클록이 필요.

- 타 기기와 통신시 클록이 일치하지 않으면 타이밍이 맞지 않음.

 

클록 제너레이터

- 클록을 만드는 회로(발진기)

- CPU 내부에 내장되어 있으며 외부 클록 신호를 사용할 수도 있음.

 

타이머 인터럽트

- CPU 내부 감산 카운터를 이용해 카운터가 0이 됬을때 인터럽트를 발생 시키는 기능

- 마스터 클록의 주기 x 0배(프리스케일러) x 세는 횟수(감산 카운터)의 시간마다 인터럽트 신호가 발생

 

명령

- 연산 관련 명령 : 산술 연산 명령, 논리 연산 명령, 시프트 연산 명령

- 연산 이외 명령 : 데이터 전송 명령, 입출력 명령, 분기 명령, 조건 판단

 

스테이터스 레지스터

- CPU 연산 결과에 따라 순서나 입출력을 제어함. 이때 판단의 기준이 플래그(1비트)

- 플래그 자체는 1비트이며 8비트나 16비트로 만든 것이 스테이터스 레지스터

 

플래그

- 제로 플래그 : 어커뮬레이터 연산 결과가 0일때

- 사인 플래그 : 연산 결과가 음수 일때

- 캐리 플래그 : 자리 올림이 발생할때

- GT 플래그 : (greater than) 보다 클때

- LT 플래그 : (less than) 보다 작을때

- 인터럽트 마스크 : 인터럽트를 받을것인지 설정

- 인터럽트 플래그 : 인터럽트가 발생한 것을 나타냄

300x250

'컴퓨터과학 > 컴퓨터, OS' 카테고리의 다른 글

가산기~주기억장치  (0) 2020.04.24
메모리~램  (0) 2020.04.23
인버터~플립플롭  (0) 2020.04.23
디지털 ~ 릴레이  (0) 2020.04.23
CPU - CPU개요, 디지털 연산  (0) 2020.04.19

+ Recent posts