2012-06-26 6 views
5

필자는 에뮬레이터가하는 일을 이해하고, 기계 언어를 다른 언어로 변경합니다. 종종 "Just-in-time"이라고합니다. 그러한 프로그램은 한 아키텍처에 대해 작성된 바이너리를 읽고 다른 아키텍처에 대한 새 바이너리를 저장한다는 점에서 빌드 될 수 있습니까? 프로세스가 완료되면 사용자는 지정된 아키텍처에서 원시 실행을 위해 바이너리를 사용할 수 있습니다. 이는 레거시 아키텍처를 위해 값 비싼 상용 응용 프로그램을 사용하는 사람들에게 특히 유용합니다.에뮬레이션을 실시간으로 수행해야하는 이유는 무엇입니까?

이러한 응용 프로그램을 만들 수 있습니까? 바이너리 재 컴파일은 새로운 개념이 아니지만 필자는 아직 그러한 유용한 구현을 찾지 못했습니다.

다른 사람들의 도움을 받아, 그러한 프로그램의 프로그래밍이 가능하다면 그러한 프로그램의 오픈 소스 구현에 대한 코딩을 시작하게되어 기쁩니다.

+1

몇 차례 완료되었습니다. 예를 들어, DEC의 FX! 32는 x86 바이너리를 다시 컴파일하여 DEC 알파에서 실행할 수 있습니다. 하지만 DEC의 (잘못된) 관리를 보충하기에는 충분하지 않았으며 Compaq/HP는 그다지 신경 쓰지 않았습니다. –

+0

에뮬레이터는 왜 존재합니까? 에뮬레이터를 쓰는 것보다이게 정말 * 어렵습니다? – user1483857

답변

0

참조 된 라이브러리가 다시 컴파일되었는지 확인해야합니다.

가능한 일이지만 엄청난 성과입니다.

이렇게해도 라이센스 문제가있을 수 있습니다. 원래 소프트웨어를 기반으로 한 파생 작업을 만들고 있습니다. 이렇게 할 수있는 대부분의 라이센스는 소스를 갖게하므로 다시 컴파일하거나 소스를 포팅 할 수 있습니다.

+0

그래서 리버스 엔지니어링으로 정확히 계산되지는 않을까요? 나는 그러한 짐승을 만들어서 법원에서 일종의 전례가있을 수 있기를 바랍니다. 유용한 응용 프로그램은 운영체제에 필요한 많은 lib가 있거나 Snow Leopard 또는 Lion에서 이식 할 수있는 OS X Mountain Lion에서 닫힌 소스 PPC 바이너리를 실행합니다. 또 하나는 lib에있는 대부분의 게임이있는 콘솔 에뮬레이션입니다. – user1483857

+1

정말로, 당신의 재 컴파일러는 : "read-> translate-> new version을 쓰십시오". 리버스 엔지니어링보다 파생 작업과 비슷합니다. 리버스 엔지니어링은 ** 그것이 무엇을하는지 이해하고 동일한 코드를 작성합니다. – WhyNotHugo

+0

유용한 응용 프로그램은 운영체제에 필요한 많은 lib가 있거나 Snow Leopard 또는 Lion에서 이식 할 수있는 OS X Mountain Lion에서 닫힌 소스 PPC 바이너리를 실행합니다. 또 하나는 lib에있는 대부분의 게임이있는 콘솔 에뮬레이션입니다. 법적 문제가 발생합니까? – user1483857

3

정적 대 동적 재 컴파일을 찾고 있다고 생각합니다. 동적 재 컴파일은 "실시간"에뮬레이션 또는 재 분류로 설명합니다. 코드는 에뮬레이터가 원래 코드의 런타임 환경을 정확하게 반영 할 수 있도록 블록으로 다시 컴파일됩니다.

정적 재 컴파일은 가능한지 묻습니다. 몇 가지 지적한 바와 같이 여러 가지 상황에서 가능하지만 정적 재 컴파일 후에 매우 특정한 런타임 제약 조건을 요구하는 코드가 성공적으로 실행되지 않을 수 있습니다. 이것이 정적 재 컴파일을 사용하는 N64 에뮬레이터 인 Corn이 매우 손으로 최적화 된 게임을 실행할 수있는 반면 동적 재 컴파일을 사용하는 다른 N64 에뮬레이터는 훨씬 더 다양한 게임을 실행하는 이유입니다.

정적 재 컴파일은 사실 더 복잡하고 전통적인 코드 (예 : x86에서 PowerPC로)에서 실제로 가능합니다. 그러나 재 컴파일러는 생성 된 정적 코드를 실행하기 위해 많은 재능을 사용해야하므로 이러한 작업은 매우 지루할 것입니다. 대상 컴퓨터에서 안정적으로 작동합니다. 동적 재 컴파일러는 개발 노력의 일부분과 성능면에서 무시할 수있는 비용으로 런타임에이를 수행 할 수 있습니다.

+0

또한 다른 아키텍처에서 부동 소수점 구현 간의 차이점이 있다고 생각하지만 확실하지 않다. –

4

정적 재 컴파일은 바이너리를 외부 아키텍처에서 다른 대상 아키텍처로 변환하는 유망한 방법입니다. 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와 정적 재 컴파일 간의 절충안은 정적으로 변환 할 수없는 비트 만 유지하면서 최대한 많은 코드를 정적으로 재 컴파일하는 것입니다.

+0

위대한 설명. 정적/동적 재 컴파일 - 캐싱 (파일에 대한)과 동적으로 재 컴파일 된 코드 청크 사이의 또 다른 가능한 절충안을 말씀 드리고자합니다. 아마도이 접근법은 런타임 분석의 '코드 경로 발견'기능으로 향상된 정적 재 컴파일의 많은 이점을 얻을 것입니다. – Cauterite

관련 문제