2016-11-06 2 views
1

Я хотел бы начать преобразование небольшого проекта nasm {synth.asm, synth_core.nh} в c, чтобы узнать немного больше об этом маленьком программном синтезаторе.C Реализация кода nasm

Проблема в моем знании asm очень очень ржавая, мне интересно, с чего начать. Я думал, что один декомпилятор может помочь мне, но я не нашел ничего открытого источника, способного конвертировать эти простые списки nasm в c.

Другой альтернативой будет делать преобразование asm-> с вручную, но я изо всех сил, чтобы понять одну из самых простых функций :(

т.е.

;distortion_machine 
;--------------------------- 
;float a 
;float b 
;--------------------------- 
;ebp: distort definition 
;edi: stackptr 
;ecx: length 
section distcode code align=1 
distortion_machine: 
    pusha 
    add ecx, ecx 
    .sampleloop: 
     fld dword [edi] 
     fld dword [ebp+0] 
     fpatan 
     fmul dword [ebp+4] 
     fstp dword [edi] 
     scasd 
    loop .sampleloop 
    popa 
    add esi, byte 8 
ret 

сломанный попытка:

void distortion_machine(???) { // pusha; saving all registers 
    int ecx = ecx+ecx; // add ecx, ecx; this doesn't make sense 

    while(???) { // .sampleloop; what's the condition? 
     float a = [edi]; // fld dword [edi]; docs says edi is stackptr, what's the meaning? 
     float b = [ebp+0]; // fld dword [ebp+0]; docs says ebp is distort definition, is that an input parameter? 
     float c = atan(a,b); // fpatan; 
     float d = c*[ebp+4]; // fmul dword [ebp+4]; 
     // scasd; what's doing this instruction? 
    } 

    return ???; 

    // popa; restoring all registers 
    // add esi, byte 8; 
} 

Я предполагаю, что приведенный выше список nasm - это очень простой цикл, искажающий простой звуковой буфер, но я не понимаю, какие из них являются входами и какие из них являются выходами. даже не понимают условия цикла: ')

Любая помощь с описанной выше процедурой и как продвигаться с этим небольшим учебным проектом будет действительно оценена.

+0

'добавить ECX, ecx' просто означает умножить ECX на два, которые имеют смысл, если функция работает на, например,' образцы short' (так 2 байта), а длина выраженные в образцах. – Jack

+1

Пожалуйста, задайте только один вопрос в сообщении. Я предполагаю, что вопрос: «Как я могу преобразовать сборку nasm в C». «Нужны предложения о том, как выполнить задание типа« »или« что делает этот код », вне темы. – BadZen

+0

@Jack Итак, предположим, что подпрограмма модифицирует «короткий» входной буфер, но «цикл» уменьшает ecx на 1, не так ли? Кроме того, в чем смысл 'ebp' и' edi' в этом контексте? – BPL

ответ

5

Там немного догадок здесь:

;distortion_machine 
;--------------------------- 
;float a << input is 2 arrays of floats, a and b, successive on stack 
;float b 
;--------------------------- 
;ebp: distort definition << 2 floats that control distortion 
;edi: stackptr   << what it says 
;ecx: length    << of each input array (a and b) 
section distcode code align=1 
distortion_machine: 
    pusha  ; << save all registers 
    add ecx, ecx ; << 2 arrays, so double for element count of both 
    .sampleloop: 
     fld dword [edi] ; << Load next float from stack 
     fld dword [ebp+0] ; << Load first float of distortion control 
     fpatan    ; << Distort with partial atan. 
     fmul dword [ebp+4] ; << Scale by multiplying with second distortion float 
     fstp dword [edi] ; << Store back to same location 
     scasd    ; << Funky way to incremement stack pointer 
    loop .sampleloop  ; << decrement ecx and jump if not zero 
    popa     ; << restore registers 
    add esi, byte 8  ; << See call site. si purpose here isn't stated 
ret 

Это реальное предположение, но esi может быть отдельный указатель стека аргументов и адреса a и b были вытеснены там. Этот код игнорирует их, делая предположения о макете стека данных, но по-прежнему необходимо удалить эти указатели из стека arg.

Примерное C:

struct distortion_control { 
    float level; 
    float scale; 
}; 

// Input: float vectors a and b stored consecutively in buf. 
void distort(struct distortion_control *c, float *buf, unsigned buf_size) { 
    buf_size *= 2; 
    do { // Note both this and the assembly misbehave if buf_size==0 
    *buf = atan2f(*buf, c->level) * c->scale; 
    ++buf; 
    } while (--buf_size); 
} 

В C повторной реализации, вы, вероятно, хотите быть более явным и зафиксировать нулевой размер буфера ошибка. Это не будет стоить много:

void distort(struct distortion_control *c, float *a, float *b, unsigned size) { 
    for (unsigned n = size; n; --n, ++a) *a = atan2f(*a, c->level) * c->scale; 
    for (unsigned n = size; n; --n, ++b) *b = atan2f(*b, c->level) * c->scale; 
} 
+0

Ничего себе, потрясающе! Большое вам спасибо, надеюсь, теперь я смогу переопределить другие аудиопрограммы, чтобы написать немного c плеера музыки. Ваш перевод c полностью имеет смысл :-D – BPL

+0

@BPL Спасибо. Примечание. Я изменил код, чтобы использовать 'atan2f', новую функцию C99 в math.h, которая обрабатывает поплавки. Если вы используете оригинал, он будет значительно медленнее из-за двойного преобразования и более медленного atan2 с двойной точностью. – Gene

+0

Да, конечно :). Прямо сейчас моя главная забота - это не скорость, а больше о том, как получить идеальный порт (тот же вывод, что и версия asm) с этого синтезатора (который предварительно вычисляет музыку сразу), после чего я попытаюсь преобразовать его в режиме реального времени синт. В любом случае, я вижу, что ваши навыки asm совершенно потрясающие. Прямо сейчас я все еще борюсь с 'esi',' edi', 'scasd' в этом contenxt, надеюсь, когда я переведу основную процедуру, они будут иметь больше смысла: D – BPL

Смежные вопросы