Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.04.2013, 20:41   #1
nati_94
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 25
По умолчанию у меня вопрос, как сдвигами число 1912h умножить на 1912h

пишу под Dos, я не очень понимаю, как это реализовать
у меня была идея
1912h=6418d=4096+2048+256+16+2
но если я делаю сдвиг больше 3х, то происходит переполнение(становиться двойным словом), и поэтому я не знаю, что делать

еще вопрос по другому заданию: можно ли как-то поделить число и результат получить, округленный до сотых или десятых,
деление также со сдвигами

Последний раз редактировалось nati_94; 26.04.2013 в 20:55.
nati_94 вне форума Ответить с цитированием
Старый 27.04.2013, 06:45   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

вообще не понимаю, при чём здесь сдвиги?!
с помощью сдвига можно умножать (делить) число только на число, явлющиеся степенью двойки (2,4,8,16 и т.д.)
при чём здесь 1912h ?!

во-вторых, если Вам запретили пользоваться операцией умножения (я правильно понял, запретили?), тогда воспользуйтесь тем, что умножение на число N, это просто повторенная N раз операция сложения.
поместите 0 в сумматор и просуммируйте его с 1912h ровно 1912h раз!

результатом будет число 2748544h
очевидно, что для суммирования вам потребуется dword (двойное слово).
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.04.2013, 07:04   #3
Mikl___
Участник клуба
 
Регистрация: 11.01.2010
Сообщений: 1,162
По умолчанию

Serge_Bliznykov,
сдвиги очень даже причем -- если 16 раз сложить одно и тоже число, то тогоже результата можно достигнуть если это число сдвинуть влево на 4 разряда
Код:
; masm dos com #
.286
.model tiny
.CODE
org 100h
start:  mov ax,x
    mov bx,ax
    xor dx,dx
    mov cx,16
@0: shr ax,1
    jnc @1;там, где ноль пропускаем, 
    add result,bx;там где единичка складываем 
    adc result+2,dx
@1: add bx,bx;и каждый раз сдвигаем число на один разряд влево
    adc dx,dx
    loop @0
    ret
x dw 1912h;=6418
result dw 0,0 ;6418^2=41190724=2748544h
end start
и сложение выполнится 16 раз, а не 1912h=6418 а если использовать команду bsr чтобы определить в каком разряде в числе 1912h находится старшая единица тогда сложение выполнится уже за 13 раз,
Код:
; masm dos com #
.286
.model tiny
.CODE
.386
org 100h
start:	mov ax,x
	bsr cx,ax
	inc cx
	mov bx,ax
	xor dx,dx
@0:	shr ax,1
	jnc @f
	add result,bx
	adc result+2,dx
@@:     add bx,bx
	adc dx,dx
	loop @0
    ret
x dw 1912h
result dw 0,0 ;2748544h
end start
а есть еще алгоритм Booth...
Код:
	movzx edx,x
	mov ebx,edx
	mov ecx,16
	xor eax,eax; clc
a0:	jnc a1
	ror ebx,1
	jnc a2
	sub eax,edx
	jmp a2
a1:	ror ebx,1
	jnc a2
	add eax,edx
a2:	shl edx,1
	loop a0
	mov result,eax
	ret
x dw 1912h
result dd 0;2748544h
end start
смысл алгоритма -- анализ двух последних бит множимого, и на основании их содержимого делается либо просто сдвиг, либо сложение и сдвиг, либо вычитание и сдвиг
оптимизированный алгоритм Booth анализируется по три бита множимого, это позводяет произвести умножение 16-разядных множимых за 8 циклов
Код:
	xor eax,eax
	cdq
	mov dx,x
	mov ebx,edx
	shl x,1
	mov ecx,8
a0:	mov bx,x
	and ebx,7
	shr x,2
	jmp dword ptr table[ebx*4]
SubLL:	sub eax,edx
	jmp LL
LSubL:	shl edx,1
	sub eax,edx
	jmp a1
LAddL:	shl edx,1
	add eax,edx
a1:	shl edx,1
	jmp a3
AddLL:	add eax,edx
LL:	shl edx,2
a3:	loop a0
	mov result,eax
	ret
x dw 1912h
result dd 0;2748544h
table dd LL,AddLL,AddLL,LAddL,LSubL,SubLL,SubLL,LL
end start
можно увеличить скорость умножения если анализировать по 4 бита множимого, в программе ниже умножение 16-разрядных чисел происходит за 6 циклов
Код:
start:	xor eax,eax
	movzx edx,x
	mov ecx,6
	shl x,1
a0:	mov bx,x
	mov esi,edx
	shl edx,3
	test bx,1000b
	jz @f
	neg esi
	not ebx
@@:	and ebx,7
	shr x,3
	test ebx,ebx
	jz a3
	inc ebx
	shr ebx,1
	cmp ebx,2
	jb a5
	jz @f
	cmp ebx,3
	jnz a6
	add eax,esi
@@:	shl esi,1
	jmp a5
a6:	shl esi,2
a5:	add eax,esi
a3:	loop a0
	mov result,eax
	ret
x dw 1912h
result dd 0;2748544h
end start

Последний раз редактировалось Mikl___; 27.04.2013 в 12:20.
Mikl___ вне форума Ответить с цитированием
Старый 27.04.2013, 11:18   #4
nati_94
Пользователь
 
Регистрация: 18.02.2013
Сообщений: 25
По умолчанию

спасибо большое всем
nati_94 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
В матрице найти число положительных элементов указанной строки и умножить это число на элементы указанного столбца. (Паскаль) Julichka1k Помощь студентам 4 18.12.2011 20:35
как умножить матрицы rostik123 Visual C++ 4 19.10.2011 21:32
Написать схематично программу с функцией, возвращающей целое число и число с десятичной точкой(Экзам. вопрос). datileo Visual C++ 1 22.06.2011 09:49
умножить число на элементы матрицы KORT Помощь студентам 2 04.11.2007 02:06