【问题标题】:C Implementation of nasm codenasm代码的C实现
【发布时间】:2016-11-06 13:33:15
【问题描述】:

我想开始将一个小的 nasm 项目 {synth.asm, synth_core.nh} 转换为 c,以了解更多关于那个小软合成器的信息。

问题是我的 asm 知识非常生疏,我想知道从哪里开始。我想也许一个反编译器可以帮助我,但我还没有找到任何能够将这些简单的 nasm 列表转换为 c 的开源代码。

另一种选择是手动转换 asm->c 但我很难理解最简单的功能之一:(

即:

;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 列表是一个非常简单的循环,会扭曲一个简单的音频缓冲区,但我不明白哪些是输入,哪些是输出,我什至不了解循环条件 :')

对于上述例程以及如何在这个小教育项目中取得进展的任何帮助,我们将不胜感激。

【问题讨论】:

  • add ecx, ecx 仅表示将 ecx 乘以 2,这在函数正在运行时有意义,例如 short 样本(即 2 个字节),长度以样本表示。
  • 请在帖子中只问一个问题。我假设问题是“如何将 nasm 程序集转换为 C”。 “需要关于如何完成 的建议”类型的问题或“这段代码做什么”在这里是题外话。
  • @RadLexus 是的,确实,我的标题有点误导,现在正在更改
  • 你将很难转换这个,因为它针对大小进行了优化,所以例如这个例程做了一些没有调用它的代码上下文就没有意义的事情。比如结尾add esi,8,而在cmets中甚至没有提到esi,结果会影响调用者。对于任何指令(scasd),请使用 google:“x86 指令 ”(有趣的是,第一个链接指向错误的描述,还包括 ESI 修改)。这里scasd 用作edi += 4; 的缩写形式。
  • 关于初始大小 = size*2 .. 由于代码使用 dword 作为示例数据,我宁愿猜测它是“立体声”调整,而不是短与字节示例? (因为我认为样本是 32b 浮点数,而不是短裤或字节).. 但我没有检查主要代码,所以我只是猜测。

标签: c assembly nasm


【解决方案1】:

这里有一些猜测:

;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;
}

【讨论】:

  • 哇,太棒了!非常感谢,希望现在我能够重新实现其他音频例程来编写音乐的小 c 播放器。您的 c 翻译完全有道理:-D
  • @BPL 谢谢。请注意,我将代码更改为使用 atan2f,这是 math.h 中处理浮点数的较新的 C99 函数。如果使用原版,由于双精度转换和双精度的 atan2 较慢,它会相当慢。
  • 是的,当然:)。现在我主要关心的不是速度,而是更多关于从那个合成器(它立即预先计算音乐)获得一个完美的端口(与 asm 版本相同的输出),之后我会尝试实时转换它合成器。无论如何,我可以看到你的 asm 技能非常棒。现在我还在为esiediscasd 在这种情况下苦苦挣扎,希望当我翻译主程序时它们会更有意义:D
  • @BPL 不能保证 atan2f lib 调用会产生与fpatan 相同的结果,但它们应该很接近。相信我的论证顺序是正确的,但如果您的结果大不相同,请尝试颠倒它们。
  • @Ped7g 我自己的产品是什么意思?如帖子中所述,这只是关于小型合成器 + asm 的一点学习练习,仅此而已。如果我想要我的“自己的产品”,我会选择现有的无数可用的开源软件合成器之一,而不是这个,它针对大小而不是速度进行了优化。我只是想在窗帘后面知道这是如何工作的。实际上,如果我正确了解 asm,我就不会尝试在 c/c++ 上对其进行编码,我会立即阅读它;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-14
  • 2013-06-28
  • 1970-01-01
  • 2014-04-26
  • 2011-08-25
  • 1970-01-01
相关资源
最近更新 更多