

Enable 신호가 1이면 연결되고 0이면 High-Z이다.

위의 ROM은 0~7 까지 총 8개의 주소를 가지고 있으며, 각 주소에서 2bit를 저장할 수 있다.
(네모박스는 메모리 셀을 의미한다)
출력하고싶은 데이터의 주소를 어드레스 라인에 입력하면, 해당되는 주소의 데이터가 출력이되는 구조이다.
예를들어 Decoder에 입력으로 101(2)를 주면 Decoder의 출력으로 5가 1이되서 각각 D1, D0 으로 메모리에 저장되어있던 값들이 출력된다.

Address Bus 는 주소 값이 전달되는 통로이다. 이는 컴퓨터마다 16비트,24비트,32비트로 다양하다.
Adress Bus가 16비트라면
최대2^(16) 개의 주소를 표현할 수 있고, 24비트라면최대2^(24) 개의 주소를 표현할 수 있고, 32비트라면최대2^(32) 개의 주소를 표현할 수 있다.
Arm 계열 MCU는
address bus가32 bit이다.
즉, 최대 4G의 주소에 접근할 수 있다.
1 Byte = 8 bit 마다 주소 한 개가 배정된다.

나는 Peripherals 중 GPIO 모듈에서 5V 전압을 출력하고싶다.
(GPIO 모듈은 0V도 출력할 수 있고 5V도 출력할 수 있다)
CPU는 저 GPIO에게 어떻게 0V를 내어라 5V 명령할 수 있을까?
GPIO 내부에는 레지스터가 존재한다.
그리고 GPIO 내부 레지스터는 특정 메모리 주소와 매핑된다.
그래서 CPU 입장에서는 메모리에 Write만 하면 된다. 그럼 자동으로 해당 주소에 매핑된 GPIO 내부 레지스터에
데이터가 Write 되고, GPIO가 동작하게된다.
(CPU가 Write하는 주소에 실물 SRAM 또는 DRAM은 존재하지 않는다. 해당 주소에는 GPIO와 같은 Peripheral 내부 레지스터가 매핑되어있다)

CPU가 메모리와 주변장치(내부에 레지스터 존재)를 인터페이스 하는 방식에는 위와 같은 대조적인 2가지 방법이 있다.
마이크로프로세서(CPU)가 입출력 장치를 액세스할 때, 입출력과 메모리의 주소 공간을 분리하지 않고
하나의 메모리 공간에 취급하여 배치하는 방식.
즉, 메모리 주소 공간의 일부가 I/O 장치 내부 레지스터와 연결 되어있다.
위와 같은 식으로 동작하게된다.
- 메모리와 I/O가 연속된 어드레스 영역에 할당되기 때문에 I/O가 차지하는 만큼 메모리 용량은 감소한다.
- CPU의 입장에서는 메모리와 I/O가 동일한 외부기기로 간주되므로 이들을 액세스하기 위한 제어신호는(read)와(write) 신호뿐이다.
- 소프트웨어적으로도 메모리에 대한 데이터의 액세스나 I/O에 대한 데이터의 입출력이 동일한 것으로 간주되므로 load나 store 명령에 의해 수행된다.
- 컴파일러의 최적화를 방지를 위해 I/O 영역 변수는 volatile로 선언해야 한다.
- RISC, 임베디드 시스템에서 주로 사용한다. (ex. ARM)
메모리와 입출력의 주소 공간을 분리하여 접근 하는 방식
- 메모리와 I/O가 별개의 어드레스 영역에 할당되기 때문에 I/O를 사용하더라도 메모리 용량은 감소하지 않는다.
- CPU의 입장에서는 메모리와 I/O 구분하여 취급해야 하므로, 이들을 액세스하기 위한 제어신호는 (read)와(write) 신호 이외에(memory request)나(I/O request) 등과 같은 구분신호가 필요하다.
- 소프트웨어적으로도 메모리에 대한 데이터의 액세스와 I/O에 대한 데이터의 입출력이 서로 다른 것으로 간주되므로, 메모리의 액세스는 load나 store 명령에 의해 수행되고 I/O의 입출력은 input이나 output 명령에 의해 수행된다.
- 주로 인텔 계열 프로세서(x86)에서 채용된다.
- 하드웨어 구성이 비교적 복잡하다.

CPU가 인식하는 메모리의 논리적(추상적) 배치
위는 ARM Coretex-M3 와 ARM Coretex-M4의 Memory Map 이다.
Arm은 MCU 칩 회사가 사용할 수 있도록 메모리 맵 구조를 미리 규정해둔다.
그럼 ST같은 제조사들은 ARM이 준 메모리맵을 보고 자기들이 만든 주변장치를 Peripheral 영역에 연결하는 것이다
전원이 공급되지 않아도 저장된 내용이 보존된다. 이 영역에는 MCU를 위한 프로그램이 저장된다.
- 메모리 주소의 첫 부분 0x00000000 에서 시작한다.
(ARM의 Adress bus는 32 bit 이다.)- 해당 영역은
Code 영역이라 부르기도하고,Flash Memory영역이라 부르기도한다.
RAM의 한 종류로, 전원이 인가될 때만 내용이 보존이 되며, 프로그램 실행 중에 프로그램에서 사용된 변수의 값을 저장하는 용도로 사용된다.
주변 장치 내부의 레지스터와 연결된 메모리 영역으로, cpu가 해당 메모리 영역에 데이터를
read하고write함으로써 주변 장치들을 제어한다.
참고로, 동일한 Arm 코어 계열 MCU라도, 제조하는 회사가 다르면 I/O 및 주변 장치가 다르기때문에, 주변 장치 제어를 위한 레지스터들의 사용 방법이 다르다
위의 Memory map은 CPU가 인식하는 메모리의 논리적(추상적) 배치 이다.
ARM은 하버드 구조이기 때문에 Flash Memory(Code) 영역 과 SRAM 영역이 실제로는 물리적으로 분리되어있다.
Arm 코어는 32bit이다. 그래서 레지스터도 전부 32비트이다.
Arm 아키텍처에서 메모리는 한 주소가 1 Byte = 8 bit를 저장할 수 있다.
그렇다면 32 비트의 레지스터 내용을 8비트씩 나누어서 메모리에 저장해야 할 것이다.
(즉, 4개의 주소의 메모리에 나누어 저장해야한다)
이 방법에는 2가지 방법이 있다.
리틀 엔디안(Little Endian) 과 빅 엔디안(Big Endian) 이다.

위와 같이 낮은 자리의 비트를 메모리의 낮은 주소에 저장하는 방식을
리틀 엔디안이라고한다.

위와 같이 낮은 자리의 비트를 높은 주소에 저장하는 방식을
빅 엔디안이라고 한다.
ARM 의 경우 두 가지 방식을 모두 지원하지만, 기본적인 방법은 리틀 엔디안 이다.

3-1에 마이크로프로세서 수업에서 배웠던 일부가 생략된 ARM-v8 의 구조이다.
(실제로는 위의 회로와 다르다. 추가적으로 레지스터를 비롯하여 다른 것들이 더 붙어있다)
위의 구조를 보면 각 타입(R,D,I,CB,B,IM)의 어셈블리 명령어가 어떤 방식으로 수행되는지 알 수 있다.