저는 이상한 문제에 봉착했습니다. this과 다소 비슷합니다. Windows Phone 8 기본 DLL 프로젝트 (대부분 C++이지만 ARM 어셈블리 소스가 포함되어 있음)가 있습니다. 소스가 ARM 모드 (즉, Thumb이 아님)입니다. C++가 Thumb으로 컴파일됩니다.WinPhone8에서 ARM (엄지 손가락 제외)이 지원됩니까?
C++이 어셈블리 루틴을 호출하려고하면 응용 프로그램이 충돌합니다. 디스 어셈블리의 call 명령은 즉각적인 오프셋을 갖는 BLX입니다. 모드를 무조건 ARM으로 다시 전환해야합니다. 그러나 어떻게 든 그럴 수는 없습니다.
예외에 대한 세부 정보가 있습니다. 예외 코드는 0xc000001d (잘못된 연산)이며 충돌 컨텍스트 구조체에있는 PC의 값은 0x696d5985입니다. 어느 모드에서도 불가능합니다. 비트가 맞지 않습니다. 비트 0은 하나입니다. BLX 명령어는 1b f0 0c eb
이됩니다. 해독하면 2 부분으로 구성된 Thumb 스타일 BLX이되며 4 개의 위치가 조정됩니다. 충돌 컨텍스트의 T 플래그는 SET (CPSR = 0x60000010)입니다.
기기가 없지만 베타 테스터의 오류 로그는 매우 결정적입니다. 어셈블리 호출하기 바로 전에 디버그 로그 레코드가 있습니다. 그 다음에 충돌.
편집 : related. 그러나 그들은 어셈블러 자체 (armasm
)가 ARM을 Thumb으로 변환한다고 주장합니다. 저에게 있어서는 그렇지 않습니다. 적어도 정적이지는 않습니다. DLL에는 어셈블리 소스 (CODE32
)에 지정된대로 올바른 ARM 코드가 포함되어 있습니다.
편집 : 약간 다른 점프의 순서로 시도 :
ldr r12, target
and r12, r12, #0xfffffffe ; To be sure
bx r12 ;BX to a register with a cleared 0th bit. Doesn't get any more explicit than that.
같은 결과. 마치 상점에서 어딘가에서 일어나는 이상한 코드 모핑이 있거나 OS 자체가 모드 스위치를 잡아서 막는 것처럼 보입니다.
코드 변형은 나머지 충돌 데이터와 함께 실행 파일의 일부를 충돌 로그에 덤프하여 감지 할 수 있습니다. 하지만 전체 코드베이스를 Thumb으로 변환하지 않으면 OS 간섭으로 무엇을 할 수 있습니까? 그것은 단지 다시 컴파일하지 않습니다. dwelch에 대한
편집 : 컴파일 된 C 코드에서 호출 순서는 다음과 같이 진행됩니다
.text:1000A35E MOV R2, #g_Host ;Three parameters
.text:1000A366 MOV R1, R5
.text:1000A368 MOV R0, R6
.text:1000A36A BLX Func ; Code bytes 1B F0 0C EB
BLX 즉시 주소로 모드를 전환 할 수 있습니다. 조건부가 아니며 bx register
과 같습니다. 호출 대상은 썽크입니다 :
.text:10025984 B Func_Impl
그리고 충돌 주소는 썽크 플러스 하나입니다 : 5985.
이 컴파일 된 DLL의 분해,하지만 난이 정확히 무엇을 실행하는 것입니다된다는 보장이 없다 장치에. 연결된 MSDN 스레드의 사용자는 디버거의 해체도 을보고 ARM이 수행해야하는 Thumb을 확인했습니다. Microsoft, IIRC, 게시자에서 장치로 경로에있는 응용 프로그램 코드 수정에 대한 특허 보유 그 이유가 될 수 있습니다.
라이브러리 및 응용 프로그램을 빌드 할 때 필요한 모든 인터 워킹 플래그를 활성화 했습니까? –
없습니다. 그리고 BLX 명령은 툴체인이 무슨 일이 벌어지고 있는지 알고 있습니다. –
hmmmmm .... 우리가 모르는 뭔가가 있어야합니다. Thumb 명령어는 매우 제한적 이었지만 Thumb2는 ARM 모드보다 훨씬 효율적인 다른 동물입니다. ARM 모드를 덤프하고 Thumb2 모드로 코딩 할 때가 된 것 같습니다. –