我想开始将一个小的nasm项目{ synth.asm,synth_core.nh }转换为c,以了解更多有关该软合成器的信息。
问题是我的asm知识非常生锈,我想知道从哪里开始。我以为也许一个反编译器可以帮助我,但是我还没有找到能将这些简单的nasm列表转换为c的开源软件。
另一种选择是手动执行转换asm-> c,但是我正在努力理解最简单的功能之一:(
IE:
;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清单是一个非常简单的循环,扭曲了一个简单的音频缓冲区,但是我不知道哪些是输入,哪些是输出,我什至都不了解循环条件:')
上面的例程以及如何完成这个小小的教育项目的任何帮助,将不胜感激。
这里有些猜测:
;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;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句