Берём
извлечения квадратного корня, ассемблер и переводим на язык JS:
// 1-в-1, как есть в ассемблере переводим в стиль Sphinx C--
// Меняем мнемонику операций в арифметические операторы
function root(x) { // x86
var
eax, ecx, edx, ebx, ebp, edi;
ebp = x + 1;
ecx = 31;
while(ebp >> ecx)
++ ecx;
ebx = 1 << (ecx & -2);
eax = 0;
do {
ecx = eax + ebx;
eax >>= 1;
edx = ecx < ebp ? -1 : 0;
edi = edx;
edx &= ecx;
ebp -= edx;
edi &= ebx;
eax |= edi;
} while(ebx >>= 2);
return eax;
}
Убераем ассемблерные трюки и в итоге получаем:
function root(x) { // JS
var
eax, ecx, edx, ebx, ebp, edi;
ebp = x + 1;
ecx = 31;
while(ebp >> ecx)
++ ecx;
ebx = 1 << (ecx & -2);
eax = 0;
do {
ecx = eax + ebx;
eax >>= 1;
if(ecx < ebp) {
ebp -= ecx;
eax |= ebx;
}
} while(ebx >>= 2);
return eax;
}
Тем самым, с языка ассемблера всё перевели в JavaScript.
Обратно, с JavaScript на язык ассемблера (i8080, Z80, 6502, 68000) перевести - дело навыков и практики. (переименовываем переменные в регистры нужного процессора, разбиваем сложные операции на кучи простейщих, заменяем математические операторы мнемониками)
function root(x) { // i8080/Z80
var
a, bc, de, hl, flags, sp = [], tmp;
hl = x + 1; // i8080:inx h
sp.push(hl); // i8080:push h
bc = 32; // i8080:mvi c,16
do {
bc --; // dcr c
flag = !(hl & 0x80000000);
hl += hl &= 0x7FFFFFFF; // dad h
} while(flag); // jnc _do_
bc &= -2; // mov a,c; ani 0feh;
hl = 1; // lxi h,1; jz _xchg_
while(bc --) // dad h
hl += hl; // dcr a; jnz _dad_
de = hl; // xchg
hl = sp.pop(); // pop h
a = 0; // xra a
do {
sp.push(a), sp.push(flags); // push psw
sp.push(hl); // push h
hl = a; // mov h,0; mov l,a
hl += de; // dad d;
tmp = hl; hl = sp.pop(); sp.push(tmp); // xthl
bc = sp.pop(); // pop b
flags = sp.pop(), a = sp.pop(); // pop psw
sp.push(de); // push d
a >>= 1; // or a; rcr
de = a; // mov e,a
a = bc; // mov a,c; cmp l; mov a,b; sbb h
flags = a < hl; // push psw
if(flags) { // jnc _pop_psw_
a = hl; a -= bc; hl = a; // mov a,l; sub c; mov l,a; mov a,h; sbb b; mov h,a
}
a = de; // pop psw; mov a,e
de = sp.pop(); // pop d
if(flags) // jnc _mov_
a |= de; // or e
de >>= 2; // mov c,a; xor a,a; mov a,d; rcr; mov d,a; mov a,e; rcr; mov e,a;
} while(de); // or d; mov a,c; jnz _do_
return a;
}
Вот и готова адаптация под i8080/Z80...