我想开始将一个小的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
Run Code Online (Sandbox Code Playgroud)
破碎的尝试:
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;
}
Run Code Online (Sandbox Code Playgroud)
我猜上面的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
Run Code Online (Sandbox Code Playgroud)
这是一个真正的猜测,但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);
}
Run Code Online (Sandbox Code Playgroud)
在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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
123 次 |
| 最近记录: |