Vadim Kudryavtsev home page

Некоторые полезные программы
 

  1. XCODE.EXE - "умный" перекодировщик текстовых файлов. Наберите XCODE.EXE имя файла, и автоматически перекодирует файл в DOS'овскую кодовую таблицу. Полезен при приеме электронный почты. Имеет возможность двойного перекодирования.
  2. RUS2ENG.EXE - перекодировщик русского текста (набранного в ДОСовской кодировке) в транслит. Очень удобная вещь для посылки писем на русском языке друзьям за границей, у которых на компьютере не установлен русский шрифт. Просто наберите RUS2ENG.EXE имя файла и в том же каталоге появится перекодированный файл с расширением *.eng.
  3. ReadCD32.EXE - проверка читабельности компакт-диска. Проходит по всему дереву каталогов. Ведет счет ошибкам чтения. Написана Николаевым Михаилом (NML).
  4. "Однокристальные 4-х разрядные микроЭВМ серии КР1820" - брошюра по серии КР1820, выпускавшейся на ПО "Интеграл".
  5. Руководство по эксплуатации радиолюбительского осциллографа Н3015.
  6. Как собрать кубик Рубика (пока только второй слой)

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.

5. Теперь наш проект полностью на C. Не забудьте включить файл ARM_to_C.h в Ваш проект.  Окончательный проект находится в директории "Full_Creference_Biquad_Project".

Если кто-то желает помочь в улучшении кода или дать свои коментарии, буду признателен. Данный код является бесплатным, Я не даю гарантию что он выдает коректно результат во всех случаях.

Программа ориентирована на исходный ARM код, написанный без ошибок.  Пока еще не полный набор ARM команд поддерживается.