2016-11-06 48 views
1

我想开始转换一个小nasm项目{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'只是由其中两个意义,如果所述功能正在工作时,例如'short'样品(SO 2个字节)乘法装置ECX及长度是以样本表示。 – Jack

+1

请在帖子中只提问一个问题。我假设问题是“我如何将nasm程序集转换为C”。 “需要关于如何完成”的类型问题或“这些代码做什么”的建议在这里是无关紧要的。 – BadZen

+0

@Jack好吧,让我们假设例程正在修改'short *'输入缓冲区,但'loop'将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可以是单独的参数堆栈指针,并ab地址已经被推那里。此代码通过对数据堆栈布局进行假设来忽略它们,但仍需要从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',它是处理浮点数的math.h中较新的C99函数。如果您使用原始文件,由于双重转换,速度会更慢,并且双精度速度会更慢。 – Gene

+0

是的,当然:)。现在我主要关心的不是速度,而是更多的关于从合成器(这是预先计算音乐一次)获得一个完美的端口(相同的输出比汇率版本),然后我会尝试实时转换它合成器。无论如何,我可以看到你的技能非常棒。现在我仍然在这个contenxt中使用'esi','edi','scasd',希望当我翻译主程序时他们会更有意义:D – BPL