· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› Помогите оптимизировать перевод числа в ASCII

. 1 . 2 . 3 . >>

Посл.отвђт Сообщенiе


Дата: Май 14, 2004 16:01:09

Помогите оптимизировать перевод числа в ASCII


Дата: Май 14, 2004 16:02:41

Делаю делением получается медленно на Athlon XP Barton 8?? тактов(для полного числа)


Дата: Май 14, 2004 16:03:33 · Поправил: Безпощадный даос

ConvertDWordToStr	proc
	;(8?? тактов)
	;edi-адрес на предпоследний символ буфера
	;eax-число для перевода
	xor		edx,edx
	mov		ebx,10
@@:
	div		ebx
	add		dl,'0'
	mov		[edi],dl
	dec		edi
	xor		dl,dl
	test	eax,eax
	jnz		@B
	inc		edi
	ret
ConvertDWordToStr endp


Дата: Май 14, 2004 16:38:37 · Поправил: Valery

0,8 = CCCCCCCD


Дата: Май 15, 2004 09:46:53

[i][/i]
Не понял


Дата: Май 15, 2004 12:05:18

Посмотрите Magic Divider by The Svin здесь


Дата: Май 15, 2004 18:45:54

Magic Divider чтука конечно полезная но мне нужен и остаток да и умноженение довольно медленное.


Дата: Май 15, 2004 20:23:11

Довольно медленное - определение не математическое, из него трудно даже приблизительно понять, а что для тебя "хорошо".
Умножение в ~4е раза быстрее деления. Остаток получаем как разность частного умноженого на 10 (умножаем 2мя однотактными командами) и прежнего числа.
На PMMX было линейное ускорение до 3х раз. На современных процах по разному.
А как ты иначе заменишь деление?
Можно изменить на вычитание степеней десятки.
Но это будет подлинней по размеру. Хотя в среднем будет чуть быстрее.

Есть более быстрый метод с табличкой в 4кб для 32х битных.


Дата: Май 15, 2004 20:48:25 · Поправил: Valery

The Svin

на вычитание степеней десятки

Вы имеете в виду что-то типа:
int div(int a, int b)
{
  int positive = !(a > 0 ^ b > 0);
  int result = 0;
  int bm;
  a = abs(a);
  b = abs(b);
  bm = b;
  while((bm << 1) <= a)
    bm <<= 1;
  while(bm >= b)
  {
    result <<= 1;
    if(a >= bm)
    {
      a -= bm;
      result++;
    }
    bm >>= 1;
  }
  return positive ? result : -result;
}


Или нет?


Дата: Май 15, 2004 21:42:04

Да обычное вычитание в цикле степени десятки с инкриминацией счётчика до переноса, компенсация последнего вычитания и переход к циклу с вычитанием следующей степени. Вычитаешь милльярды, сотни миллионов и т.д. Это очень примитивно выглядит и занимает много байт но работает быстро, чуть быстрее в среднем чем оптимизация деления вытеснением в старшие разряды. По крайней мере так было давным давно когда я это проверял на PMMX.


Дата: Май 15, 2004 21:48:35

Табличку можно использовать из 16 байт (с ascii символами цифр). Так еще и избавимся от add dl,'0'
Индекс в табличке получаем из бит 31..34 результата EDX:EAX :
;;  edx - число
mov eax,CCCCCCCDh
mov ecx, 7
mul edx
and ecx, edx
shr edx, 3
add eax, eax
rcl ecx, 1
mov al, [esi+ecx]
mov [edi], al


Дата: Май 15, 2004 22:01:52

Valery

А что это ты такое написал? Я немного прибалдел. Теорию подвести можешь?


Дата: Май 15, 2004 23:10:05

S_T_A_S_
Почему на СССССССВ?
Забыл раскладку переключить. А удалил, так как после медитации понял, что все там до меня было сказано ...


Дата: Май 15, 2004 23:12:47 · Поправил: S_T_A_S_

Black_mirror

Сорри.. А то я уже сижу на калькуляторе считаю :-)
imho объяснение грамотно начиналось..


Дата: Май 15, 2004 23:25:12

.data
align 8
dig1    = '0'
dig2    = '0'
dig3    = '0'
len = 1
tblXDec2Asc equ $
REPT 1000
dd len shl 24 + dig3 shl 16 + dig2 shl 8 + dig1
if len eq 1
  dig1=dig1+1
  if dig1 gt '9'
    len=2
    dig1='1'
  endif
elseif len eq 2
  dig2=dig2+1
  if dig2 gt '9'
    dig2='0'
    dig1=dig1+1
    if dig1 gt '9'
      len=3
      dig1='1'
    endif
  endif
elseif len eq 3
  dig3=dig3+1
  if dig3 gt '9'
    dig3='0'
    dig2=dig2+1
    if dig2 gt '9'
      dig2='0'
      dig1=dig1+1
    endif
  endif
endif
ENDM

; edi-buffer for string
; eax-number
.code

DwordDec2Asc proc uses esi ebx lpBuffer,lpNumber
        mov eax,lpNumber
        mov edi,lpBuffer
        mov ebx,esp
@@lpG:  mov ecx,eax
        mov edx,10624DD3h
        mul edx
        shr edx,6
        imul eax,edx,1000
        sub ecx,eax
        mov eax,edx
        push [tblXDec2Asc+4*ecx]
        or  eax,eax
        jne @@lpG
        sub ebx,esp
        pop eax
        mov ecx,eax
        mov [edi],eax
        shr  ecx,24
        jmp [tbl-4+ebx]
.data
align 4
tbl     dd  @@0,@@1,@@2,@@3
.code
@@3:    pop dword ptr [edi+ecx]
	 add ecx,3
@@2:    pop dword ptr [edi+ecx]
	 add ecx,3
@@1:    pop dword ptr [edi+ecx]
        	add ecx,3
@@0:    add edi,ecx
	mov byte ptr [edi],0
        ret
DwordDec2Asc endp

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.050