정적 재 컴파일은 바이너리를 외부 아키텍처에서 다른 대상 아키텍처로 변환하는 유망한 방법입니다. Just-In-Time (JIT)보다 빠르다. 왜냐하면 실행하기 직전에 코드를 컴파일 할 필요가 없기 때문이다. 컴파일 시간을 단축하면 코드 생성을 최적화하는 것이 유용하기 때문이다.
그러나 정적 재 컴파일은 정적 프로그램 분석 (따라서 이름)에 의존하는 반면 JIT 컴파일은 동적 프로그램 분석을 사용합니다.
정적 분석에서 실행에 대한 런타임 정보가 없습니다.
간접 점프가이 문제에 중점을 둡니다. 이 용어는 특정 switch
문에서 생성되거나 함수 포인터를 사용하거나 런타임 다형성 (가상 테이블을 생각하는)에서 생성 될 수있는 코드를 다룹니다. 그것은 모든 형태의 명령어로 귀결 :
JMP reg_A
은의 당신이 당신의 프로그램의 시작 주소를 알고 있다고 가정 해 봅시다, 당신은이 시점에서 지침을 다시 컴파일하기 시작했다. 직접 점프가 발생하면 대상 주소로 이동하고 거기에서 재 컴파일을 계속합니다. 간접적 인 점프를 만나면, 당신은 붙어 있습니다. 이 어셈블리 명령에서
reg_A
의 내용은 정적으로 알 수 없습니다. 따라서 다음 명령어의 주소를 알 수 없습니다. 동적 재 컴파일에서는 레지스터의 가상 상태를 에뮬레이션하고
reg_A
의 현재 내용을 알기 때문에이 문제가 발생하지 않습니다. 게다가 정적 재 컴파일에서 가능한 모든 경로를 컴파일하려고하므로이 시점에서 에 대해 가능한 값
을 찾는 데 관심이 있습니다. 동적 분석에서는 현재 실행중인 경로를 생성하기 위해 현재 값만 필요하며 reg_A
값을 변경해야 다른 경로를 생성 할 수 있습니다. 경우에 따라 정적 분석을 통해 후보 목록을 찾을 수 있습니다 (switch
에 가능한 오프셋 표가 있어야 함). 일반적으로 알 수없는 일반적인 경우입니다. 미세한라고 말하면 이진 파일의 모든 지침을 다시 컴파일 해 봅시다!
여기의 문제는 대부분의 바이너리에는 코드와 데이터가 모두 포함되어 있다는 점입니다. 아키텍처에 따라 어떤 아키텍처인지 알 수 없을 수도 있습니다.
일부 아키텍처에서는 정렬 제약 조건과 가변 폭 명령어가 없기 때문에 어느 시점에서 분해가 시작되어 오프셋을 사용하여 다시 컴파일을 시작했음을 알 수 있습니다.
의 두 가지 지시 사항을 포함하는 단순화 된 명령어 세트와 단일 레지스터 A
보자 41 42
하는의 시작점이 첫 번째 바이트 41
입니다 가정 해 봅시다 :
41 xx (size 2): Add xx to `A`.
42 (size 1): Increment `A` by one.
이의 다음 바이너리 프로그램을 보자를 . 당신은 할 수 :
41 42 (size 2): Add 42 to `A`.
그러나 (41)의 경우는 데이터의 조각이다? 그런 다음 프로그램이된다 :
42 (size 1): Increment `A` by one.
이 문제는 종종 어셈블리에 직접 최적화 된 오래된 게임에 확대하고, 프로그래머 수도 의도적으로 expect some byte to be interpreted as both code and data, depending on the context!
설상가상 재 컴파일 프로그램이 될 수있는 곳 생성하는 코드 자체! JIT 컴파일러를 다시 컴파일한다고 상상해보십시오. 결과는 여전히 소스 아키텍처에 대한 코드를 출력하고 바로 가기로 이동하여 프로그램이 곧 종료 될 가능성이 높습니다. 런타임에만 사용 가능한 코드를 정적으로 다시 컴파일하려면 무한한 속임수가 필요합니다!
정적 바이너리 분석은 (주로 보안 분야에서 소스를 사용할 수없는 시스템의 취약점을 찾는) 매우 실용적인 연구 분야이며 실제로는 NES emulator that tries to statically recompile programs을 생성하려는 시도를 알고 있습니다. 이 기사는 매우 흥미 롭습니다.
JIT와 정적 재 컴파일 간의 절충안은 정적으로 변환 할 수없는 비트 만 유지하면서 최대한 많은 코드를 정적으로 재 컴파일하는 것입니다.
몇 차례 완료되었습니다. 예를 들어, DEC의 FX! 32는 x86 바이너리를 다시 컴파일하여 DEC 알파에서 실행할 수 있습니다. 하지만 DEC의 (잘못된) 관리를 보충하기에는 충분하지 않았으며 Compaq/HP는 그다지 신경 쓰지 않았습니다. –
에뮬레이터는 왜 존재합니까? 에뮬레이터를 쓰는 것보다이게 정말 * 어렵습니다? – user1483857