Некоторые
полезные программы
ARM2C -
Конвертер ARM кода в C сод
ARM2C.zip
- загрузить
исходники и пример
История обновлений:
2012.09.18 -
оригинальный релиз
2012.09.23 -
обновление
- исправлено распознавание
паттерна в LDR/STR командах
- крэш вовремя
парсинга команды теперь отлавливается.
сообщение
об ошибке вставляется в оттранслированный C код
2012.10.03 -
обновление
- исправлена ошибка
распознавание паттерна при наличии суффикса или флага
- исправлена проблема
операнда "op2" распознавание паттернов для LDR/STR команд
- добавлены
LDRB/STRB, LDM/STM команды
2012.10.08 -
обновление
- обновлена таблица
условий
- добавлены CLZ и
другие команды в таблицу макросов
- улучшена обработка
условий
Похожие проекты:
Этот проект появился тогда, когда я обнаружил что некоторые файлы, содержащие референсный C код были утеряны или даже никогда не создавались. я был вынужден работать с кросс-компилятором. Компиляция и особенно симуляция на PC оказалась очень медленной по сравнению с работой над референсным Visual Studio проектом, написанным полностью на C коде.
Я нашел несколько проектов декомпилятора в интернете, но только один из них (Hex-Rays) имел возможность транслировать код ассемблера ARM в C код. Этот проект очень хорошего качества (поклон разработчикам ), но к сожалению его цена достаточно высока.
Так что я решил в свободное время (дома) написать простой транслятор ARM кода в C код, который позволил бы мне восстановить референсные C файлы (несмотря на то, что результат трансляции может быть достаточно примитивен) и запустить полный проект на Visual Studio.
Это
- первая версия, и моей целью было написать программу результатом
которой была бы
адекватная трансляция тела ассемблерной функции в С код (жертвуя
оптимизацией и
удобочитаемостью), который я смог бы откомпилировать и запустить на Visual
Studio. Так что не бейте меня ногами :-), но здоровой критике я буду
рад.
Как оттранслировать ARM код в C:
1.
Каталог
"Original_asm_Biquad_Project" содержит исходный проект простой
обработки
аудио потока. Однако один файл написан на ARM ассемблере. наша цель -
конвертировать
этот файл в эквивалентный C код, чтобы получить проект, написанный
полностью на
C.
2. Сконвертируем его с помощью программы
ARM2C
ARM2C.exe -oARM2C_biquad.c -ibiquad.s
ниже представлен результат трансляции
Таблица 1. Частичный результат трансляции.
ARM Assembler (biquad.s) | C Equivalent (ARM2C_biquad.c) |
; load states ldmia r3, {r8-r9} ; load counter ldr r14, [sp,#4*9] biquad_Loop ldrsh r2, [r1],#2*2 smlawb r2, r8, r7, r2 smlawt r2, r9, r7, r2 smulwb r12, r8, r6 smlawt r12, r9, r6, r12 mov r2, r2, lsl#(16-QCOEFF) smlawb r12, r2, r5, r12 strh r12, [r0],#2*2 mov r9, r8 ; update states mov r8, r2 subs r14, r14, #1 bgt biquad_Loop ; save states stmia r3, {r8-r9} |
// load
states { int* p=(int*)r3; { r8 = *p; p+=1; r9 = *p; p+=1; } } // load counter r14 = *((int*)(sp+(4*9))); biquad_Loop: r2 = (int)(*((short*)r1)); r1+=2*2; r2 = (int)((((INT64)r8 * (short)r7)>>16) + r2); r2 = (int)((((INT64)r9 * (short)(r7>>16))>>16) + r2); r12 = (int)(((INT64)r8 * (short)r6)>>16); r12 = (int)((((INT64)r9 * (short)(r6>>16))>>16) + r12); r2 = (r2<<((16-QCOEFF))); r12 = (int)((((INT64)r2 * (short)r5)>>16) + r12); (*((unsigned short*)r0)) = (unsigned short)r12; r0+=2*2; // update states r9 = r8; r8 = r2; r14 = r14 - (1);s=r14; if (s>0){goto biquad_Loop;} // save states { int* p=(int*)r3; { *p = r8; p+=1; *p = r9; p+=1; } } |
3. Полученный файл ARM2C_biquad.c
пока еще
не готов к компиляции.
-
во-первых,
просмотрим весь файл на наличие сообщений "ERROR !!! -> some
code <-
this line is not
recognized". если код, выделенный таким сообщением, не является
важным(какая-нибудь
команда препроцессора или комментарий), просто закоментируйте
сообщение. В противном
случае вам придется вручную транслировать данную ассемблерную команду.
Извините,
но пока еще трансляция не всех команд поддерживается.
-
во-вторых, нужно заменить фиктивную декларацию
функции на настоящую из соответствующего header файла.
- в
третьих, нужно проставить правильное количество
параметров для PARAMETER_NUMBER, и затем раскомментировать требуемое
количество
операторов, записывающих параметры p4 и выше в массив, имитирующий
стек. Это необходимо,
поскольку в соответствии с соглашением по вызову функций из C кода
первые четыре
параметра располагаются в регистрах r0-r3, а остальные помещаются в
стек. Мы используем
внутренний массив для имитации стека.
Таблица
2. Коррекция оттранслированного результата.
Original translation | Required correction |
//
Replace this function declaration by true declaration from
corresponding header file int Biquad_proc (int p0, int p1, int p2, int p3) { int r0=(int)p0, r1=(int)p1, r2=(int)p2, r3=(int)p3; int r4=0, r5=0, r6=0, r7=0, r8=0, r9=0, r10=0, r11=0, r12=0, /*r13=0,*/ r14=0, r15=0; int s=0; #define STACK_DEPTH 20 #define PARAMETER_NUM 4 // number of function parameters int stack_array[STACK_DEPTH+PARAMETER_NUM-4]; // parameters after 4th one are stored in the stack // stack allocated for these parameters int* sp_p=(stack_array+STACK_DEPTH); int sp=(int)sp_p; // sp_p[0]=(int)p4; sp_p[1]=(int)p5; //... // store all parameters after 4th one in the stack #undef STACK_DEPTH #undef PARAMETER_NUM |
//
Replace this function declaration by true declaration from
corresponding header file //int biquad (int p0, int p1, int p2, int p3) void Biquad_proc( short(*p0/*out*/)[2], short(*p1/*in*/)[2], short* p2/*coeffs*/, int* p3/*state*/, int p4/*n*/) { int r0=(int)p0, r1=(int)p1, r2=(int)p2, r3=(int)p3; int r4=0, r5=0, r6=0, r7=0, r8=0, r9=0, r10=0, r11=0, r12=0, /*r13=0,*/ r14=0, r15=0; int s=0; #define STACK_LENGTH 20 #define PARAMETER_NUM 5 // number of function parameters int stack_array[STACK_LENGTH+PARAMETER_NUM-4]; // parameters after 4th one are stored in the stack // stack allocated for these parameters int* sp_p=(stack_array+STACK_LENGTH); int sp=(int)sp_p; sp_p[0]=p4;// sp_p[1]=p5; //... // store all parameters after 4th one in the stack #undef STACK_DEPTH #undef PARAMETER_NUM |
4. Проделав такою модификацию для всех функций, мы получим код эквивалентный коду оригинального ARM файла на ассемблере. Возможно, он выглядит не очень элегантно, не оптимален, но тем не менее он уже может быть скомпилирован на компиляторе C.
Если
кто-то желает помочь в улучшении кода или дать свои коментарии, буду
признателен. Данный код является бесплатным, Я не даю гарантию что он
выдает коректно результат
во всех случаях.
Программа
ориентирована на исходный ARM код, написанный без ошибок. Пока еще не полный набор
ARM команд поддерживается.