
무슨 일이 있었냐면
“지금 윈도우 11에서 실행되는 가장 오래된 GUI 프로그램은 뭘까?” 한 개발자가 이 질문의 답을 찾아본 글을 블로그에 올렸어요. 레트로 감성 놀이처럼 보이지만, 파고들수록 운영체제가 하위 호환성을 어떻게 지켜왔는지, 그리고 어디서 선을 그었는지가 그대로 드러나요.
macOS는 2019년 Catalina에서 32비트 앱 지원을 통째로 끊었고, 리눅스에서는 몇 년 된 바이너리가 라이브러리 버전 문제로 안 뜨는 일이 흔하잖아요. 그런데 윈도우에서는 수십 년 된 프로그램이 더블클릭 한 번에 뜨는 경우가 많아요. 어떻게 이게 가능한지 하나씩 풀어볼게요.
첫 번째 벽: 16비트 프로그램
윈도우 1.0(1985년)부터 3.x 시절까지의 프로그램은 대부분 16비트예요. 아쉽지만 이 프로그램들은 윈도우 11에서 돌아가지 않아요.
32비트 윈도우에는 NTVDM과 WOW(Windows on Windows)라는 장치가 있어서 DOS 프로그램과 16비트 프로그램을 돌릴 수 있었어요. 그런데 x64 CPU가 64비트 모드로 동작할 때는 DOS 프로그램을 돌리던 가상 8086 모드를 쓸 수 없어요. 16비트 윈도우 지원 계층도 64비트로 옮겨봤자 얻는 것보다 잃는 게 많다고 봐서 64비트 윈도우에서는 빠졌어요. 윈도우 11은 64비트 전용이니 16비트 앱은 공식적으로 실행할 수 없는 거예요.
그래도 재밌는 예외가 하나 있어요. 옛날 설치 프로그램 중에는 16비트로 만든 게 많았는데, 64비트 윈도우는 널리 쓰이던 16비트 설치 프로그램을 알아보면 32비트 버전으로 슬쩍 바꿔서 실행해줘요. 호환성에 얼마나 공을 들이는지 보여주는 대목이에요.
진짜 후보는 Win32 시대부터
그래서 답은 32비트 Win32 API로 만든 프로그램 중에서 찾아야 해요. Win32가 처음 나온 건 1993년 출시된 Windows NT 3.1 무렵이에요. 이 시절 프로그램이 지금도 돌아가는 이유는 크게 두 가지예요.
첫째, 실행 파일 형식이 그대로예요. PE(Portable Executable)라는 형식인데, .exe 파일 안에 코드와 데이터를 어떤 구조로 담을지 정한 규칙이에요. NT 3.1 때 정한 이 형식을 윈도우 11 로더가 여전히 읽을 수 있어요. 64비트 윈도우는 WOW64라는 계층을 통해 32비트 프로그램을 자연스럽게 실행해주고요.
둘째, API를 지우지 않는다는 원칙이에요. CreateWindow, GetMessage, DispatchMessage 같은 Win32 GUI 기본 함수들은 30년 넘게 같은 이름, 같은 동작으로 남아 있어요. 새 기능이 필요하면 CreateWindowEx처럼 이름에 Ex를 붙인 함수를 새로 추가할 뿐, 원래 있던 함수는 고치지 않아요.
버그까지 떠안는 호환성
조엘 스폴스키가 「How Microsoft Lost the API War」에서 소개한 유명한 일화가 있어요. 윈도우 95를 개발하던 시절, 심시티에는 이미 해제한 메모리를 계속 읽는 버그가 있었는데 새 메모리 관리자에서는 이게 크래시로 이어졌대요. 그래서 마이크로소프트는 심시티가 실행될 때만 메모리 관리자가 예전처럼 동작하도록 특별 처리를 넣었어요. 다른 회사 앱의 버그까지 호환성의 일부로 떠안은 거예요. 이런 처리는 지금도 호환성 심(shim) 으로 남아 있어요. 프로그램 속성에서 ‘호환성 모드’를 켜면 OS가 버전을 속여주거나 특정 API를 예전처럼 동작하게 해주는데, 이게 바로 그 장치예요.
업계 맥락
리눅스 쪽에는 “리눅스에서 가장 안정적인 ABI는 Win32”라는 반쯤 농담 같은 말이 있어요. 커널은 사용자 공간을 깨뜨리지 않는다는 원칙을 철저히 지키지만, GUI 라이브러리 같은 사용자 공간 쪽은 버전이 바뀌면 오래된 바이너리가 쉽게 깨지거든요. 그러다 보니 Wine이나 Proton으로 윈도우용 게임을 돌리는 쪽이 오히려 더 오래 안정적으로 돌아가는 아이러니가 생겨요. 애플은 반대예요. Rosetta 같은 과도기 도구를 준 다음 시간이 지나면 과감하게 정리해요. 플랫폼은 깔끔해지지만 오래된 소프트웨어는 버려지게 돼요.
한국 개발자에게 주는 시사점
국내에는 아직 오래된 윈도우 프로그램에 기대는 현장이 많아요. 공공기관, 제조 설비 제어, 금융권 내부 시스템 같은 곳이요. 32비트 Win32 프로그램이라면 윈도우 11로 옮겨도 살아남을 가능성이 높아요. 하지만 16비트 구성 요소가 섞여 있다면 가상 머신 같은 대책을 따로 세워야 해요. 레거시 마이그레이션을 검토할 때는 실행 파일이 16비트인지부터 확인하는 게 첫 단계예요.
API를 설계하는 입장이라면 “지우지 말고 추가하라”는 원칙도 곱씹어볼 만해요. 버전 한 번 올릴 때마다 사용자를 깨뜨리는 라이브러리와 30년 전 코드도 살려두는 플랫폼의 차이가 결국 생태계의 신뢰를 만들거든요.
마무리
윈도우는 64비트로 넘어가면서 16비트를 놓아줬지만, Win32 시대 프로그램은 30년 넘게 지켜내고 있어요. 원문에서 저자가 실제로 어떤 프로그램까지 거슬러 올라갔는지 따라가 보는 것도 재밌을 거예요.
여러분 주변에서 아직 현역으로 돌아가는 가장 오래된 프로그램은 뭔가요? 그리고 ‘깔끔하게 끊는 애플식’과 ‘끝까지 지키는 윈도우식’ 중 어느 쪽이 더 낫다고 생각하세요?
🔗 출처: Hacker News