Показать сообщение отдельно
  #14 (permalink)  
Старый 19.03.2015, 18:48
Аватар для Paguo-86PK
Профессор
Отправить личное сообщение для Paguo-86PK Посмотреть профиль Найти все сообщения от Paguo-86PK
 
Регистрация: 16.09.2009
Сообщений: 253

Заготовка для ассемблера: Извлечение корня
Берём извлечения квадратного корня, ассемблер и переводим на язык 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...

Последний раз редактировалось Paguo-86PK, 19.03.2015 в 18:52.
Ответить с цитированием