본문 바로가기

CS 공부/컴파일러

[컴파일러] 백패칭

백패칭

GOTO문의 전방 점프나 if 분기 구문 같은 경우에는 내부적으로 점프를 사용하는데 점프할 부분의 소스 코드가 읽히지 않아 점프의 번지를 지정할수 없는 상태이므로 중간 코드에 빠진 부분을 만들어 놓고 해당 점프의 목표 부분을 찾으면 점프의 번지를 결정한다. 이것을 백패칭이라고 하는데 이렇게만 써놓아서는 이해가 잘 안되므로 간단한 C언어와 어셈블리 코드를 예시로 들어 설명하겠다.

if (x==y) {
    x=-1;
} else {
    x=1;
}

위의 C언어는 어셈블리로 다음과 같이 표현된다.

  MOV _x, R1
  CMP _y, R1
  JE EQUAL
  MOV  1, _x
EQUAL:
  MOV  -1, _x

위의 어셈블리 코드에서 중요한 부분은 JE EQUAL이다. 이 코드의 뜻은 한단계 전의 CMP가 참이면 (여기서는 yx의 값이 같으면) (JE: Jump if Equal) EQUAL로 이동하라는 뜻인데 컴파일러가 EQUAL: MOV -1, _x을 읽어들이기 전이므로 EQUAL에 해당하는 주소를 찾을 수 없기 때문에 JE EQUAL을 기계어로 바꿀 수 없어 비워 두었다가 EQUAL: MOV -1, _x 을 발견하면 점프의 번지를 결정해서 JE EUQAL의 기계어 변환을 완료하게 된다. 이를 백패칭이라고 한다. 분기를 사용하는 모든 코드는 백패칭을 사용해서 목적 기계어로 만들어지기 때문에 GOTO를 사용한 코드도 같은 맥락으로 백패칭이 적용된다.

 
goto A;
A:
  x=1;

어셈블리로 다음과 같이 표현된다.

  JMP A
A:
  MOV  1, _x

(A가 나올 때까지 비워 두었다가 A가 나타나면 백패칭을 통해 점프 번지 결정)