본문 바로가기
임베디드 개발/8051

8051 메모리 구조

by eteo 2026. 7. 30.
반응형

 

 

1. 8051이란?

일반적으로 8051이라고 부르는 것은 1980년 인텔이 발표한 8비트 마이크로컨트롤러 8051 하나만을 뜻하는 것이 아니라, 이후 등장한 8031, 8032, 8052, 8751, 8752, 89C51, 89C52, 80C31, 80C32 등 동일한 명령어 집합(ISA)을 기반으로 하는 8051 프로세서 계열 전체를 통칭하는 표현이다.

 

그리고 인텔이 8051 시장에서 철수하고 원천 특허가 만료된 이후에는 STC, Silicon Labs, Nuvoton, Infineon, Megawin 같은 여러 반도체 업체가 표준 8051 아키텍처에 고속 클록, 확장 메모리, I2C / SPI / USB 같은 현대적인 인터페이스를 얹은 호환 칩을 자체적으로 찍어내고 있다.

 

따라서 오늘날 8051라는 용어는 특정 제조사의 MCU를 의미하는 것이 아니고,  8051 호환 MCU 계열 전체를 일컫는 용어로 사용된다.

 

 

 

 

 

2. 8051 메모리 구조

8051의 메모리 구조는 크게 프로그램 메모리(Program Memory)와 데이터 메모리(Data Memory)로 나눌 수 있고, 두 메모리 공간은 서로 독립적인 주소 공간을 사용한다.

 

이건 현대 MCU가 플래시, SRAM, 주변장치를 하나의 통합된 메모리 맵으로 관리하는 것과 다른 점이다. 현대 MCU에서는 플래시는 0x08000000, SRAM은 0x20000000처럼 서로 다른 주소를 갖지만, 8051에서는 프로그램 메모리와 데이터 메모리가 각각 0000H부터 시작할 수 있다. 따라서 같은 주소(ex: 1234H)라도 프로그램 메모리의 1234H인지, 데이터 메모리의 1234H인지에 따라 전혀 다른 위치를 의미하며, CPU는 실행하는 명령어(MOV, MOVC, MOVX)를 통해 어느 메모리 공간에 접근할지를 구분한다.

 

 

 

2.1. 프로그램 메모리

프로그램 메모리는 Read-Only(읽기 전용) 공간으로, CPU가 실행할 코드가 저장된다. MCU가 리셋되면 CPU는 프로그램 카운터(PC)를 0000H로 초기화하고 해당 주소부터 명령어를 실행하기 시작한다. 이때 PC는 16비트 크기의 레지스터이므로 프로그램 메모리는 최대 64KB(0000H ~ FFFFH)까지 표현할 수 있다.

 

 

✓ 프로그램 메모리가 Read-Only라는 뜻

CPU 입장에서 프로그램 메모리는 명령어를 가져오는(Fetch) 용도로만 접근하는 공간이다. 물리적으로는 플래시 메모리이므로 기록이 가능한 매체지만, 일반적인 CPU의 메모리 쓰기 명령(Write instruction)으로는 플래시 메모리에 데이터를 기록할 수 없다. 플래시를 갱신하려면 플래시 컨트롤러(Flash Controller)를 이용한 별도의 프로그래밍 절차가 필요하며, 8051 계열에서는 ISP(In-System Programming)와 IAP(In-Application Programming) 기능을 통해 이를 수행한다.

 

 

IAP (In-Application Programming)

일반적으로  IAP라고 하면 부트로더를 통한 펌웨어 업데이트를 뜻하지만, 8051 MCU에서는 애플리케이션이 실행 중인 상태에서 특정 Flash 영역을 데이터 저장소처럼 쓰기 위해 Program/Read/Erase하는 기능까지 포함해서 IAP라고 부른다.

 

 

 

한편, 인터럽트를 처리하기 위한 인터럽트 벡터는 프로그램 메모리의 0003H 주소부터 위치한다. External Interrupt 0은 0003H, Timer 0 000BH와 같이 인터럽트 종류마다 8바이트 간격으로 주소가 고정 배치되어 있다. 인터럽트가 발생하면 CPU는 해당 벡터 주소로 분기하는데, 이때 인터럽트 서비스 루틴(ISR)의 크기가 8바이트 이내라면 해당 위치에서 바로 실행할 수 있지만, 보통은 이보다 길기 때문에 벡터 위치에는 LJMP 명령어를 두어 실제 ISR이 있는 주소로 점프하도록 구현한다.

 

 

MOV DPTR, #1234H  		; 읽을 프로그램 메모리 주소를 지정
CLR A             				; 누산기(A) 레지스터를 0으로 만듦 (A = 00H)
MOVC A, @A+DPTR   		; 0 + 1234H = 1234H 주소의 값을 읽어옴

 

 

 

 

2.2. 내부 데이터 메모리 (SRAM)

데이터 메모리는 변수와 스택 등 런타임 데이터를 저장하는 공간이며, 주변장치 제어를 위한 특수 기능 레지스터(SFR)들도 이 메모리 주소 영역에 함께 매핑되어 있다.

 

8051에서 내부 데이터 메모리에 접근할 때 사용하는 명령어는 주소 필드가 8비트다. 따라서 표현 가능한 주소 범위는 00H~FFH, 즉, 총 256바이트(Bytes)로 제한된다.

이 256바이트 공간의 가장 큰 특징은 'Upper 128 Bytes SRAM'과 'SFR' 영역이 80H~FFH라는 동일한 주소 범위를 공유한다는 점이다. 둘은 물리적으로 완전 별개의 메모리 공간이며, CPU는 주소 지정 방식(Addressing Mode)에 따라 어느 영역에 접근할지를 결정한다.

 

 

  • 직접 주소 지정(Direct Addressing) 시: 주소 값을 명령어에 직접 명시하면 SFR 영역으로 접근한다.
MOV A,90H			; 90H 주소에 매핑된 SFR(P1 레지스터)의 값을 읽어옴

 

  • 간접 주소 지정(Indirect Addressing) 시: 레지스터를 거쳐 주소를 가리키면 Upper 128바이트 SRAM 영역으로 접근한다.
MOV R0,#90H
MOV A,@R0			;	Upper RAM의 90H 주소에 저장된 값을 읽어옴



즉, 같은 90H 라는 주소라도 어떤 방식으로 접근하느냐에 따라 전혀 다른 메모리 공간을 가리키게 된다. 이게 8051 데이터 메모리의 가장 큰 특징이다.

 

 

 

한편, Lower 128 Bytes RAM은 Direct와 Indirect Addressing 방식의 접근을 모두 지원하며, 다시 세가지 영역으로 나뉜다.

 

 

  • Register Bank (00H ~ 1FH)
    • 내부 RAM의 최하위 영역(00H ~ 1FH)에 위치한다. 각각 8개의 범용 레지스터(R0 ~ R7)로 이루어진 4개의 뱅크(Bank 0 ~ 3)로 구성되어 총 32 Bytes 크기를 가진다.
    • 현재 사용할 Bank는 PSW(Program Status Word) 레지스의 RS1, RS0 비트로 선택한다.
    • 레지스터 접근 명령어는 일반 메모리 접근보다 실행 속도가 빠르고 효율적이어서, 자주 사용하는 변수나 임시 데이터를 처리할 때 유리하다.
    • 특히 인터럽트 서비스 루틴(ISR)에 메인 프로그램과 다른 독립된 레지스터 뱅크를 할당해서 사용하면, 기존 레지스터 값을 일일이 스택에 백업(PUSH)하고 복원(POP)하는 오버헤드를 줄일 수 있다.
  • Bit-addressable RAM (20H ~ 2FH)
    • 총 16 Bytes(128 bits) 크기의 Bit-addressable 영역이다.
    • 일반적인 바이트 단위 접근뿐만 아니라, 이 영역 내에 포함된 총 128개의 각 비트마다 고유의 비트 주소(00H ~ 7FH)가 할당되어 있다. 
    • 덕분에 비트 제어 명령어(SETB, CLR, JB 등)를 사용해 한 줄의 명령으로 개별 비트를 직접 제어할 수 있어, 각종 플래그 관리나 비트 단위의 I/O 제어에 매우 유용하다.
  • General-purpose RAM (30H ~ 7FH)
    • 나머지 80 Bytes 크기의 공간으로, 일반 사용자 변수 저장 공간 및 스택(Stack) 영역으로 활용된다.
    • 스택 영역(.STACK)은 낮은 주소에서 위로 확장되며 하위 RAM(~7FH) 뿐만 아니라 Indirect Addressing 상위 RAM(~FFH) 공간까지 쌓일 수 있다.
    •  
    • 8051은 리셋 시 스택포인터(SP)가 07H로 초기화되는 특징이 있다. 이 상태에서는 스택이 레지스터 뱅크 영역을 침범할 수 있으므로, 일반적으로 Startup 어셈 코드에서 SP 시작 위치를 사용자 정의 변수 영역 이후 주소로 재설정해 쓴다.

 

 

 

 

 

 

2.3. SFR (Special Function Register)

SFR은 MCU 내부의 다양한 주변장치를 제어하기 위한 전용 레지스터 공간이다. 입출력 포트(GPIO), 타이머, UART, 인터럽트 컨트롤러 등 하드웨어 제어 레지스터가 여기에 위치한다.

앞서 언급했듯이 Upper 128 Bytes RAM과 동일한 주소 공간(80H~FFH)을 공유하며, Upper RAM과 구별하기 위해 Direct Addressing 방식으로만 접근해야 한다.

또한, SFR 중에서 주소의 하위 4비트가 0H 또는 8H로 끝나는 레지스터들(ex. 80H, 88H, 90H 등)은 비트 단위 제어가 가능한 'Bit-addressable SFR'로 지정되어 있다.

 



  SFR 공간의 확장
오리지널 8051 아키텍처는 128바이트의 SFR 공간만 제공하지만, 현대의 고성능 8051 호환 MCU(STC, Nuvoton 등)들은 내부 주변장치가 대거 추가됨에 따라 SFR 주소가 부족하게 되었다. 이를 해결하기 위해 많은 제조사가 SFR Page 또는 SFR Bank 라는 매커니즘을 도입하여, 동일한 주소 영역이라도 특정 페이지 레지스터 값을 변경함으로써 수백 개의 확장 레지스터를 스위칭하며 사용할 수 있도록 지원하고 있다.

 

 

 

 

2.4. 외부 데이터 메모리 (XRAM)

 

CPU 내부의 256 Bytes Internal RAM만 가지고는 실제 응용에서 공간이 부족한 경우가 많다. 이를 해결하기 위해 현대의 많은 8051 호환 MCU들은 KB 규모의 외부 데이터 메모리(XRAM) 공간을 MCU 칩 내부에 통합하여 제공한다.

 

XRAM 영역에 접근할 때는 Internal RAM 접근시 사용하는 MOV 명령어 대신, 외부 데이터 메모리 전용 접근 명령어인 MOVX를 사용 한다. 또한 16비트 크기의 데이터 포인터 레지스터 DPTR을 사용해 최대 64KB(0000H ~ FFFFH) 주소 공간에 접근할 수 있다.

 

MOV DPTR, #1234H				;	DPTR 레지스터에 XRAM의 16비트 주소(1234H)를 로드
MOVX A, @DPTR				; 	DPTR이 가리키는 XRAM 주소의 값을 읽어옴

 

 

 

 

 

 

 

 

 

2.5. 펌웨어 개발 관점의 메모리 접근 방식

결국 CPU는 명령어(opcode)를 보고 어떤 메모리 공간에 접근할지 결정하지만, C 펌웨어 개발자가 이러한 어셈블리 명령어를 일일이 고려하며 코드를 짜진 않는다.

 

MOV A, 30H						; Internal RAM -> Accumulator
MOVX A, @DPTR				; XRAM -> Accumulator
MOVC A, @A+DPTR				; Program Memory 접근 -> Accumulator

 

대신 컴파일러가 제공하는 메모리 확장 키워드(data, idata, xdata 등)를 통해 “이 변수를 어느 메모리 영역에 둘 것인지”를 지정하고, 그에 맞는 실제 접근 명령어(MOV, MOVX, MOVC 등)는 컴파일러가 자동으로 생성해 준다.

대표적으로 Keil C51 컴파일러는 다음과 같은 메모리 키워드들을 지원한다.

 

키워드 실제 매핑 영역 하드웨어 접근 방식 특징 및 용도
data Lower 128B of
Internal RAM (00H~7FH)
Direct Addressing 접근 속도가 가장 빠름, 자주 쓰는 변수 배치
idata Internal RAM 전체
(00H~FFH)
Indirect Addressing 내부 RAM의 Upper 128B 까지 포함하여 변수 배치
bdata Bit-addressable RAM
(20H~2FH)
비트 및 바이트 접근 혼용 비트 단위로 쪼개 쓸 수 있는
범용 변수용
bit Bit-addressable RAM
(20H~2FH)
비트 명령어
(SETB, CLR 등)
Flag 변수용
sfr SFR Direct Addressing 주변장치 제어 레지스터 정의
sbit Bit-addressable
RAM 또는 SFR
비트 명령어
(SETB, CLR 등)
SFR 레지스터의 특정 비트나 개별 I/O 핀에 이름을 붙여 직접 제어할 때 사용
xdata XRAM 전체
(0000H ~ FFFFH)
MOVX @DPTR 대용량 버퍼, 배열, 구조체 등
pdata XRAM 중 256B 한 페이지 MOVX @R0 8비트 주소만 사용하여 XRAM에 빠르게 접근 가능
256B의 링버퍼 등
code 프로그램 메모리
(0000H ~ FFFFH)
MOVC @A+DPTR 읽기 전용 상수, 룩업 테이블,
문자열 등 저장

 

C 코드에서 변수를 선언할 때 어떤 키워드를 붙이느냐에 따라 실제 생성되는 어셈블리 코드와 실행 속도가 달라진다.

 

unsigned char data  buf1[32];  // Lower 128B of Internal RAM에 배치, MOV 명령 한 줄로 접근
unsigned char xdata buf2[256]; // XRAM에 배치, MOVX 명령어와 DPTR 세팅 필요

 

예를 들어, 위와 같이 선언 시 data 영역은 MOV 명령 한 줄로 끝나지만, xdata는 16비트 주소를 다루기 위해 DPTR 레지스터를 세팅하는 과정이 선행되어야 하므로 명령어 수가 늘어나고 CPU 사이클을 더 많이 소비한다.

 

따라서 자주 쓰는 변수는 data에 배치하고, 크기가 큰 버퍼나 실시간성이 중요하지 않은 데이터는 idata/xdata에 두는 변수 배치 전략이 필요하다. 또한, 내부 RAM은 스택으로 사용되므로 너무 많은 전역 변수를 배치하면 스택 오버플로우가 발생할 수 있다는 점도 고려해야 한다.

 

 

✓ bit과 sbit의 차이

  • bit : Bit-addressable RAM(0x20~0x2F)에 실제 1비트 변수 공간을 독립적으로 할당한다.
  • sbit : 이미 존재하는 bdata 변수나 sfr 레지스터의 특정 비트에 이름을 붙여 접근하는 일종의 Alias 개념이다.

 

✓ pdata 사용 시 제약

pdata는 8비트 레지스터(R0 또는 R1)를 사용해 'MOVX @R0, A' 형태로 xdata 공간에 접근하므로, 이 때 상위 8비트 주소(Page) 값이 필요하다. 이 상위 주소는 보통 P2(Port 2) 또는 특정 SFR이 담당하게 되며, 해당 레지스터 세팅과 pdata 변수 배치를 일치시키는 사전 작업이 필수적이다.

  1. Startup 코드에서 PPAGEENABLE을 1로 설정하고 사용할 페이지 번호(PPAGE)를 지정한다.
  2. Keil uVision5 프로젝트 설정 > 링커 설정에서 pdata 상위 주소 범위를 동일하게 지정한다.

 

반응형

'임베디드 개발 > 8051' 카테고리의 다른 글

8051 MCU의 1T, 6T, 12T의 의미  (0) 2026.07.23