질문)
dos os는 주소기반으로 하드웨어등이 접근되었는데, 예를들어 c언어로 모니터 스크린에 출력시에
char *address = (char far *)0xB800000;
*(address + 0) = 'a';
*(address + 1) = 0xff; //텍스트의 fore color, background color
으로 할당해서 코드했습니다. windows에서도 위와 같은 주소기반으로 코드를 할수 있나요?
답변)
예전 MS-DOS처럼 물리 메모리 주소를 직접 지정해서 0xB8000 같은 주소로 하드웨어 직접 제어하던 방식은,
Windows에서는 (일반 사용자 프로세스에서는) 불가능합니다.
그 이유는 다음과 같습니다:
🚫 Windows에서 주소 직접 접근이 안 되는 이유
✅ 1. 보호 모드 운영체제(Protected Mode)
- Windows는 32/64비트 보호 모드 운영체제입니다.
- 운영체제가 **프로세스마다 가상 메모리 공간(Virtual Memory)**을 제공하고,
- 직접적인 물리 주소 접근은 커널 모드에서만 가능하게 막아 놓았습니다.
✅ 2. 메모리 보호(Memory Protection)
- 예를 들어 0xB8000은 VGA 텍스트 버퍼의 물리 주소입니다.
- Windows에서는 **일반 프로세스가 이 영역을 직접 접근하면 예외(Access Violation)**가 발생합니다.
- 사용자 모드에서는 해당 주소에 접근할 권한이 없습니다.
✅ 그럼 Windows에서는 어떻게 해야 하나요?
▶️ 방법 1. 콘솔 API 사용 (표준 출력)
- DOS에서 직접 메모리 접근으로 하던 일을, Windows에서는 API 함수로 대신합니다.
c
복사편집
#include <windows.h> #include <stdio.h> int main() { HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); DWORD written; WriteConsoleA(h, "Hello, world!", 13, &written, NULL); return 0; }
▶️ 방법 2. 콘솔 버퍼 직접 조작
- Windows에서도 VGA 텍스트 모드처럼 콘솔 버퍼를 직접 편집하는 API가 있습니다.
CHAR_INFO buffer[80]; COORD size = {80, 1}; COORD pos = {0, 0}; SMALL_RECT rect = {0, 0, 79, 0}; for(int i = 0; i < 80; i++) { buffer[i].Char.AsciiChar = 'A' + (i % 26); buffer[i].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY; } HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsoleOutputA(h, buffer, size, pos, &rect); |
▶️ 방법 3. 드라이버 수준에서 물리 메모리 접근 (고급)
- 정말 물리 주소(0xB8000 등)를 직접 접근하고 싶다면:
- 커널 모드 드라이버를 작성해야 합니다 (예: Windows Driver Kit 사용)
- 또는 WinRing0, inpout32.dll, giveio.sys 같은 물리 메모리/포트 접근 라이브러리를 사용해야 합니다
- 하지만 이는 보안상 위험하며 관리자 권한 필요 + 디지털 서명된 드라이버 요구 (윈도우 10/11 기준)
🔍 참고: DOS vs Windows 메모리 모델 비교
항목DOS (실모드)Windows (보호모드)
주소 접근 | 물리 주소 직접 지정 (0xB8000) | 가상 주소만 사용, 직접 지정 불가 |
권한 | 모든 하드웨어 직접 제어 가능 | 하드웨어는 커널만 접근 가능 |
메모리 모델 | 1MB, 세그먼트:오프셋 | 가상 주소 공간 (4GB/64bit) |
예시 | char far *vid = (char *)0xB8000; | ❌ (불가) |
✅ 결론
- Windows에서는 DOS처럼 물리 주소를 직접 지정해서 접근하는 방식은 일반적으로 불가능합니다.
- 대신, Windows API를 통해 간접적으로 출력하거나,
- 하드웨어 제어가 필요할 경우엔 커널 드라이버 수준에서 작업해야 합니다.