핵심 요약
- 교육용 16비트 아키텍처 LC-3 바이너리를 텍스트 어셈블리로 변환하는 디스어셈블러를 하스켈로 구현한 개발기입니다.
- LC-3 바이너리는 심볼이나 코드/데이터 분리 섹션이 없어 16비트 값만으로는 명령인지 데이터인지 구분하기 어렵다는 고유한 문제가 있습니다.
- 명확한 명령어를 먼저 디코딩한 뒤 문맥을 바탕으로 추측 분석을 반복하는 멀티패스 방식으로 문제를 해결했습니다.
요약 컴퓨터 구조나 어셈블리 교육용으로 널리 쓰이는 가상 아키텍처 'LC-3(Little Computer 3)'의 바이너리를 역어셈블(디스어셈블)하는 하스켈(Haskell) 구현기가 공개되었습니다. LC-3는 16비트 레지스터 8개와 18개의 단순한 명령어 세트를 갖추고 있어 초심자 교육용으로 가상머신(VM)이나 어셈블러를 직접 만들어보는 과제로 자주 활용됩니다.
그러나 바이너리 오브젝트 파일을 다시 사람이 읽을 수 있는 텍스트 어셈블리 코드로 복원하는 디스어셈블러를 만드는 과정에는 독특한 난관이 따릅니다. x86이나 Arm 같은 최신 바이너리와 달리, LC-3 오브젝트 파일에는 코드와 데이터를 구분해 주는 섹션 테이블이나 심볼 테이블, 디버그 정보가 전혀 존재하지 않기 때문입니다. 16비트 주소 공간 안에 순수 바이너리 명령어와 데이터가 마구 뒤섞여 저장되다 보니, 특정 16비트 값이 유효한 명령어(예: JSRR R6)인지 아니면 단순 문자열, 숫자 리터럴, 메모리 주소인지 구분할 방법이 없습니다.
작성자는 이러한 문제를 해결하기 위해 문맥 기반의 다단계(multi-pass) 파싱 기법을 적용했다고 설명합니다. 먼저 명확하게 판별되는 명령어들을 1차적으로 디코딩한 뒤, 해당 명령어들의 전후 맥락을 활용해 나머지 영역이 명령어인지 데이터인지 추측(speculative decode)하며 고정점(fix-point)에 도달할 때까지 반복 처리합니다. 이후 바이트 단위 데이터를 병합해 정리하고, 적절한 위치에 레이블을 다시 삽입하는 방식으로 하스켈 코드를 구현해 나갑니다.
Sponsored · 광고