Article View: pl.comp.lang.asm
Article #2558Re: Konwersja dużych liczb
From: Bogdan (bogdro)
Date: Tue, 10 Sep 2013 17:50
Date: Tue, 10 Sep 2013 17:50
98 lines
4758 bytes
4758 bytes
W dniu 10.09.2013 12:22, Kamil pisze:
> Użytkownik "Bogdan (bogdro)" napisał:
>
>> Wszystko się zgadza. Przed ostatnim znakiem mnożysz ostatni raz
>> liczbę przez 10, po czym dodajesz ten ostatni znak.
>
> Dzięki Tobie przeanalizowałem jeszcze raz procedurę. Przyjrzałem się
> dokładnie poniższej procedurce:
>
> [code]
>
> pobieraj:
> mov bl, [esi]
> cmp bl, 0
> jz _do_ret
> cmp bl, 20h
> jz pomin
> cmp bl, 40h
> ja _blad1
Jeśli chciałeś tym odfiltrować tylko cyfry, to jest w tym drobny
błędzik. Jeśli dobrze pamiętam, znak dwukropka przejdzie ten test, bo
dwukropek to 3A. '9' < 3a < 40h. Tak więc powinno być pewnie
cmp bl, '9'
ja _blad1
Ale może tak to było zaprojektowane (może inny mechanizm w kontrolce
nie pozwoli na wpisanie innego znaku).
Jeśli faktycznie miały być brane tylko cyfry, to czytelniej, moim
zdaniem, będzie tak:
cmp bl, ' '
jz pomin
cmp bl, '0'
jb _blad1
cmp bl, '9'
ja _blad1
Kompilator sam wstawi odpowiednie wartości bajtów w miejsce spacji ('
'), znaku '0' i '9'.
> cmp bl, 30h
> jb _blad1
> sub bl, 30h
> mul ecx ; wynik jest w eax
> jc _blad2
> add eax, ebx
> [/code]
>
> Bardzo zręczne rozwiązanie. Pierwsze mnożenie jest "puste". Dzięki
> temu ostatni znak nie jest mnożony. Z tego wzorca korzystłem tworząć
> iterację wielokrotnej precyzji. Wszystko było dobrze z małymi wyjątkami:
>
> pushf
> add esi, 4
> add edi, 4
> popf
>
> O czym juz chyba wspomniałem. Brakowało odtworzenia flag w iteracji.
> Jednak w dalszym ciągu były błędy dla niektórych danych wejściowych.
> Sprawa okazała sie banalna. Było:
>
> add dword ptr [esi], ebx
> adc dword ptr [esi+4], 0
> adc dword ptr [esi+8], 0
>
> zmieniłem na:
>
> add dword ptr [esi], ebx
> adc dword ptr [esi+4], 0
> adc dword ptr [esi+8], 0
> adc dword ptr [esi+12], 0
>
> Można się załamać szukając tak prostej przyczyny. Czy teraz jest już
> wystarczająca ilość adc? Ile ich powinno być, aby być całkowicie pewnym?
A tak mi się coś właśnie wydawało, że te bufory jakichś dziwnych
długości były, ale nie przyjrzałem się dość dokładnie.
Dodawanie (ADD i ADC) będzie tylko w mnożeniu i dodawaniu.
Wynik mnożenia może mieć co najwyżej tyle bitów, ile bitów miały
łącznie wszystkie czynniki. Jeśli mnożysz dwie liczby 32-bitowe, wynik
nie przekroczy 64 bitów (więc mieści się w EDX:EAX). Jeśli mnożysz
dwie liczby 128-bitowe (po 4 dwordy każda), wynik nie przekroczy 256
bitów (8 dwordów).
Innymi słowy, gdy pobierasz liczbę np. dwa razy (w dwóch częściach) -
z [ESI] i [ESI+4], instrukcje dodawania (pierwsze ADD i dalsze ADC)
musisz powtórzyć 4 razy, np. do [EDI], [EDI+4], [EDI+8] i [EDI+12].
Jeśli po ostatniej z tych instrukcji flaga CF jest ustawiona, to masz
przepełnienie.
A w dodawaniu instrukcje ADD/ADC powtarzasz tyle razy, ile ma dłuższy
ze składników sumy. Dla liczb 128-bitowych (4 dwordy) piszesz łącznie
4 instrukcje - jedną ADD i trzy ADC, jak w przykładzie powyżej.
--
Pozdrawiam/Regards - Bogdan (GNU/Linux & FreeDOS)
Kurs asemblera x86 (DOS, GNU/Linux):http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm: pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
www.Xiph.org www.TorProject.org Soft(EN): tinyurl.com/bogdro-soft
Technical Details
Message-ID:
<522f5be5$0$1450$65785112@news.neostrada.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin1!goblin.stu.neva.ru!news.glorb.com!news-out.readnews.com!transit3.readnews.com!nx01.iad01.newshosting.com!newshosting.com!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-a-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mailReferences:
<52239cda$0$1225$65785112@news.neostrada.pl> <522a0fcd$0$1459$65785112@news.neostrada.pl> <522a4a2c$0$1268$65785112@news.neostrada.pl> <522b5a7a$0$1263$65785112@news.neostrada.pl> <522c61b4$0$1470$65785112@news.neostrada.pl> <522dfbe2$0$1267$65785112@news.neostrada.pl> <522ef313$0$1261$65785112@news.neostrada.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!agh.edu.pl!news.agh.edu.pl!newsfeed2.atman.pl!newsfeed.atman.pl!goblin1!goblin.stu.neva.ru!news.glorb.com!news-out.readnews.com!transit3.readnews.com!nx01.iad01.newshosting.com!newshosting.com!newsfeed.neostrada.pl!unt-exc-01.news.neostrada.pl!unt-spo-a-01.news.neostrada.pl!news.neostrada.pl.POSTED!not-for-mail Date: Tue, 10 Sep 2013 19:50:28 +0200 From: "Bogdan (bogdro)" <bogdan@poczta.gazeta.pl> User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130801 Thunderbird/17.0.8 MIME-Version: 1.0 Newsgroups: pl.comp.lang.asm Subject: Re: Konwersja dużych liczb References: <52239cda$0$1225$65785112@news.neostrada.pl> <522a0fcd$0$1459$65785112@news.neostrada.pl> <522a4a2c$0$1268$65785112@news.neostrada.pl> <522b5a7a$0$1263$65785112@news.neostrada.pl> <522c61b4$0$1470$65785112@news.neostrada.pl> <522dfbe2$0$1267$65785112@news.neostrada.pl> <522ef313$0$1261$65785112@news.neostrada.pl> In-Reply-To: <522ef313$0$1261$65785112@news.neostrada.pl> Lines: 98 Message-ID: <522f5be5$0$1450$65785112@news.neostrada.pl> Organization: Telekomunikacja Polska NNTP-Posting-Host: rudy.mif.pg.gda.pl X-Trace: 1378835431 unt-rea-a-01.news.neostrada.pl 1450 153.19.42.16:57437 X-Complaints-To: abuse@news.neostrada.pl Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit