🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.asm
5 messages
5 total messages Started by Kamil Fri, 06 Sep 2013 01:57
Odejmowanie dużych liczb
#2565
Author: Kamil
Date: Fri, 06 Sep 2013 01:57
85 lines
3278 bytes
Witam

Na stronie Bogdana jest min. procedura odejmowania:


 mov eax, [arg1]
 sub eax, [arg2]     ; odejmujemy 2 pierwsze części
 mov [wynik], eax    ; i zapisujemy wynik
                     ; flaga CF mówi, czy była pożyczka

 mov eax, [arg1+4]
 sbb eax, [arg2+4]   ; odejmujemy razem z pożyczk? (CF),
                     ; jeśli w poprzednim odejmowaniu
                     ; musieli?my co? pożyczać

 mov [wynik+4], eax  ; wynik: [arg1+4]-[arg2+4]-pożyczka
                     ; z pierwszego odejmowania
                     ; CF teraz zawiera pożyczkę z SBB
                     ; podobnie reszta działania:

 mov eax, [arg1+8]
 sbb eax, [arg2+8]
 mov [wynik+8], eax

 mov eax, [arg1+12]
 sbb eax, [arg2+12]
 mov [wynik+12], eax

 jc arg1_mniejszy_od_arg2

Moja implementacja wygląda tak:

odejmij PROC

 push esi
 push edi
 push ebx
 push ebp


 mov eax, [arg1]
 sub eax, [arg2]     ; odejmujemy 2 pierwsze części
 mov [wynik], eax    ; i zapisujemy wynik
                     ; flaga CF mówi, czy była pożyczka

 mov eax, [arg1+4]
 sbb eax, [arg2+4]   ; odejmujemy razem z pożyczk? (CF),
                     ; jeśli w poprzednim odejmowaniu
                     ; musieli?my co? pożyczać

 mov [wynik+4], eax  ; wynik: [arg1+4]-[arg2+4]-pożyczka
                     ; z pierwszego odejmowania
                     ; CF teraz zawiera pożyczkę z SBB
                     ; podobnie reszta działania:

 mov eax, [arg1+8]
 sbb eax, [arg2+8]
 mov [wynik+8], eax

 mov eax, [arg1+12]
 sbb eax, [arg2+12]
 mov [wynik+12], eax

 jc arg1_mniejszy_od_arg2

arg1_mniejszy_od_arg2:

 pop ebp
 pop ebx
 pop edi
 pop esi

   ret

odejmij endp

mam następujące pytania:

- Co sie stanie w razie wystąpienia sytuacji spełniącej warunek skoku jc?
  Czy linia  mov [wynik+12], eax się wykona? Jaki będzie wynik?

- co się stanie kiedy już w peerwszych argumentach będzie  arg1 < arg2
- cfzy jc nie powinno być po każdym odejmowaniu?

Pozdrawiam
Re: Odejmowanie dużych liczb
#2566
Author: Kamil
Date: Fri, 06 Sep 2013 06:04
53 lines
1862 bytes
Użytkownik "Kamil" napisał:

Ta procedura działa błędnie dla niektórych danych wejściowych.
Pryczyny nie znalazłem. Może komuś uda się znaleźć błąd?

[code]

 push edi
 push esi
 push ebx
 push ebp

 mov esi, odarg1
 mov edi, odkarg2
 mov ebx, odwynik
 mov ecx, 20

 mov eax, pam [esi]
 sub eax, pam [edi]
 mov pam [ebx], eax

odejmujemy:

 mov eax, pam [esi+4]
 sbb eax, pam [edi+4]
 mov pam [ebx+4], eax

 jc arg1_mniejszy_od_arg2

 add esi, 4
 add edi, 4
 add ebx, 4

 loop odejmujemy


arg1_mniejszy_od_arg2:

 pop ebp
 pop ebx
 pop esi
 pop edi

 mov eax, 'aw'
 jmp _do_ret_od2

_do_ret_od2:

   ret

[/code]

Pozdrawiam
Re: Odejmowanie dużych liczb
#2569
Author: Bogdan (bogdro)
Date: Fri, 06 Sep 2013 17:29
109 lines
4058 bytes
W dniu 06.09.2013 03:57, Kamil pisze:
> Witam
> 
> Na stronie Bogdana jest min. procedura odejmowania:
> 
> 
> mov eax, [arg1]
> sub eax, [arg2]     ; odejmujemy 2 pierwsze części
> mov [wynik], eax    ; i zapisujemy wynik
>                     ; flaga CF mówi, czy była pożyczka
> 
> mov eax, [arg1+4]
> sbb eax, [arg2+4]   ; odejmujemy razem z pożyczk? (CF),
>                     ; jeśli w poprzednim odejmowaniu
>                     ; musieli?my co? pożyczać
> 
> mov [wynik+4], eax  ; wynik: [arg1+4]-[arg2+4]-pożyczka
>                     ; z pierwszego odejmowania
>                     ; CF teraz zawiera pożyczkę z SBB
>                     ; podobnie reszta działania:
> 
> mov eax, [arg1+8]
> sbb eax, [arg2+8]
> mov [wynik+8], eax
> 
> mov eax, [arg1+12]
> sbb eax, [arg2+12]
> mov [wynik+12], eax
> 
> jc arg1_mniejszy_od_arg2
> 
> Moja implementacja wygląda tak:
> 
> odejmij PROC
> 
> push esi
> push edi
> push ebx
> push ebp
> 
> 
> mov eax, [arg1]
> sub eax, [arg2]     ; odejmujemy 2 pierwsze części
> mov [wynik], eax    ; i zapisujemy wynik
>                     ; flaga CF mówi, czy była pożyczka
> 
> mov eax, [arg1+4]
> sbb eax, [arg2+4]   ; odejmujemy razem z pożyczk? (CF),
>                     ; jeśli w poprzednim odejmowaniu
>                     ; musieli?my co? pożyczać
> 
> mov [wynik+4], eax  ; wynik: [arg1+4]-[arg2+4]-pożyczka
>                     ; z pierwszego odejmowania
>                     ; CF teraz zawiera pożyczkę z SBB
>                     ; podobnie reszta działania:
> 
> mov eax, [arg1+8]
> sbb eax, [arg2+8]
> mov [wynik+8], eax
> 
> mov eax, [arg1+12]
> sbb eax, [arg2+12]
> mov [wynik+12], eax
> 
> jc arg1_mniejszy_od_arg2
> 
> arg1_mniejszy_od_arg2:
> 
> pop ebp
> pop ebx
> pop edi
> pop esi
> 
>   ret
> 
> odejmij endp
> 
> mam następujące pytania:
> 
> - Co sie stanie w razie wystąpienia sytuacji spełniącej warunek skoku jc?

 Nic. To jest "informacja dla autora", że gdyby chciał tę sytuację
obsłużyć, to może zrobić to w ten sposób.

>  Czy linia  mov [wynik+12], eax się wykona?

 Tak, bo jest przed skokiem.

> Jaki będzie wynik?

 Ten sam. Konkretnie - ujemny.

> - co się stanie kiedy już w peerwszych argumentach będzie  arg1 < arg2

 Nic. Liczby będą się dalej odejmować, tylko flaga CF będzie
gdzieniegdzie ustawiona.

> - cfzy jc nie powinno być po każdym odejmowaniu?

 Nie. Sytuacja ustawienia flagi CF jest obsługiwana przez zastosowanie
instrukcji SBB (odejmowanie "z pożyczką") zamiast SUB, czyli zwykłego
odejmowania.


-- 
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
Re: Odejmowanie dużych liczb
#2567
Author: Bogdan (bogdro)
Date: Fri, 06 Sep 2013 17:36
71 lines
2673 bytes
W dniu 06.09.2013 08:04, Kamil pisze:
> Użytkownik "Kamil" napisał:
> 
> Ta procedura działa błędnie dla niektórych danych wejściowych.

 Czym otrzymany wynik różni się od oczekiwanego?

> Pryczyny nie znalazłem. Może komuś uda się znaleźć błąd?
> 
> [code]
> 
> push edi
> push esi
> push ebx
> push ebp
> 
> mov esi, odarg1
> mov edi, odkarg2
> mov ebx, odwynik
> mov ecx, 20
> 
> mov eax, pam [esi]
> sub eax, pam [edi]
> mov pam [ebx], eax

 Bez definicji "pam" może być trudno to zinterpretować.


> odejmujemy:
> 
> mov eax, pam [esi+4]
> sbb eax, pam [edi+4]
> mov pam [ebx+4], eax
> 
> jc arg1_mniejszy_od_arg2
> 
> add esi, 4
> add edi, 4
> add ebx, 4
> 
> loop odejmujemy

 Wiesz, że odejmujesz 21 "czwórek", prawda? ECX = 20, ale pozycję [0]
obsługujesz przed pętlą, a w pętli obsługujesz pozycje [4], [8], [12],
..., [80], czyli łącznie bajty na offsetach od 0 do 83 włącznie.

> arg1_mniejszy_od_arg2:
> 
> pop ebp
> pop ebx
> pop esi
> pop edi
> 
> mov eax, 'aw'
> jmp _do_ret_od2
> 
> _do_ret_od2:
> 
>   ret
> 
> [/code]
> 
> Pozdrawiam
> 


-- 
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
Re: Odejmowanie dużych liczb
#2568
Author: Kamil
Date: Fri, 06 Sep 2013 21:54
54 lines
2509 bytes
Użytkownik "Bogdan (bogdro)" napisał:

>> Ta procedura działa błędnie dla niektórych danych wejściowych.

> Czym otrzymany wynik różni się od oczekiwanego?

Dla np. 633825300114114700748351602688 wynik dzielenia wynosi 
554597137599850363154807652352

>> Pryczyny nie znalazłem. Może komuś uda się znaleźć błąd?

> Bez definicji "pam" może być trudno to zinterpretować.

Przepraszam za przeoczenie. "pam" equ dword ptr


>> mov eax, pam [esi+4]
>> sbb eax, pam [edi+4]
>> mov pam [ebx+4], eax
>>
>> jc arg1_mniejszy_od_arg2
>>
>> add esi, 4
>> add edi, 4
>> add ebx, 4

>> loop odejmujemy

> Wiesz, że odejmujesz 21 "czwórek", prawda? ECX = 20, ale pozycję [0]
> obsługujesz przed pętlą, a w pętli obsługujesz pozycje [4], [8], [12],
> ..., [80], czyli łącznie bajty na offsetach od 0 do 83 włącznie.

To akurat jest jasne. Wydaje się, że jeden błąd znalazłem. Otóż jeśli po sbb 
zostanie ustawiona flaga to linijki

    add esi, 4
    add edi, 4
    add ebx, 4

ją skasują. Ma być tak:

    pushf

    add esi, 4
    add edi, 4
    add ebx, 4

    popf

Okazuje się, że "skaracanie" tekstu źródłowego procedur jest ryzykowne. 
Lepiej stosować je w pełnym rozwinięciu wg. Twoich tutoriali. Wtedy nie ma 
problemów.

Pozdrawiam
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads