레지스터 이름보다 역할을 먼저 보기
레지스터 창을 열면 긴 16진수와 익숙하지 않은 이름이 한꺼번에 나타납니다. 처음부터 모든 이름을 외울 필요는 없습니다. 먼저 다음 실행 위치를 가리키는 프로그램 카운터, 현재 스택 위치를 나타내는 스택 포인터, 함수가 계산 결과를 돌려줄 때 사용하는 레지스터를 구분해 보세요. x86-64 환경에서는 RIP와 RSP라는 이름이 흔하지만 다른 아키텍처에는 다른 이름이 있습니다. DBG Desk의 메모리 조회에서 사용하는 $pc와 $sp는 GDB가 제공하는 일반적인 별칭입니다. 특정 레지스터의 역할을 이해할 때는 대상 아키텍처와 호출 규약을 함께 확인해야 합니다.
프로그램 카운터는 실행 흐름의 기준
현재 명령어 주소는 디스어셈블리에서 어떤 행을 실행할 차례인지 판단하는 기준입니다. 산술 명령어 다음에는 가까운 다음 주소로 이동하는 경우가 많지만 분기, 호출, 반환 명령어를 만나면 멀리 이동할 수 있습니다. 주소가 갑자기 바뀌었다고 해서 곧바로 잘못된 점프라고 판단하지 마세요. 직전 명령어가 call이나 ret였는지, 조건 분기가 선택되었는지를 먼저 봅니다. 함수 진입과 반환을 몇 차례 따라가면 레지스터 값이 코드의 흐름과 어떻게 연결되는지 보입니다. 실행 중에는 값이 계속 변하므로 정지한 시점의 스냅샷을 기준으로 비교해야 합니다.
같은 비트도 다르게 해석될 수 있다
레지스터에 보이는 숫자는 타입 정보가 붙은 고급 언어 변수가 아닙니다. 같은 비트 패턴도 정수, 주소, 플래그 또는 임시 계산값으로 쓰일 수 있습니다. 특히 x86-64에서 EAX와 RAX는 별개의 독립 저장 공간으로 생각하면 안 됩니다. EAX에 값을 쓰면 상위 32비트가 지워지는 동작이 있지만 AL처럼 작은 부분을 쓰는 경우의 규칙은 다릅니다. 명령어가 어느 크기의 피연산자를 사용하는지 함께 읽어야 값이 바뀐 이유를 설명할 수 있습니다. 16진수 숫자가 낯설다면 그 값을 무조건 포인터로 열기보다 직전 연산이 무엇이었는지부터 확인하세요.
변경 표시를 결론으로 삼지 않기
DBG Desk는 이전 조회와 비교해 바뀐 레지스터를 파란색으로 표시합니다. 이는 변경이 있었다는 단서이며 그 변경이 오류라는 뜻은 아닙니다. 함수 호출 후 임시 레지스터가 달라지는 것은 호출 규약에 따라 정상일 수 있습니다. 반환값이 어느 레지스터에 놓이는지도 Windows x64, 다른 플랫폼, 부동소수점 반환 등 조건에 따라 달라집니다. 의심하는 계산의 앞뒤에서 어떤 명령어가 값을 썼는지 기록하고, 해당 값이 이후에 어디로 전달되는지 따라가세요. 관찰한 비트와 프로그램에서 기대한 의미를 연결하는 과정이 레지스터 분석의 핵심입니다.
작은 정수 하나로 확인하기
accumulate가 2를 받아 7을 돌려주는 호출을 골라 계산 전후를 비교해 보세요. 소스의 value라는 이름과 같은 이름의 레지스터가 있을 것이라고 기대할 필요는 없습니다. 명령어가 값을 어디서 읽고 어느 레지스터에 결과를 쓰는지 따라가면 됩니다. 반환 직전의 값을 확인한 뒤 호출자에서 그 값이 합계에 더해지는 지점도 봅니다. 중간 레지스터가 나중에 다른 용도로 쓰이더라도 계산이 잘못됐다는 뜻은 아닙니다. 호출이 끝난 뒤에도 유지되어야 하는 값과 잠깐 쓰이는 값을 구분하면 숫자가 계속 바뀌는 화면을 더 차분하게 읽을 수 있습니다. 관찰은 같은 빌드의 정지 지점끼리 비교합니다.