-
11. Data: 2015-10-05 21:47:04
Temat: Re: asm - przesuwanie wektora bajtow
Od: "M.M." <m...@g...com>
On Monday, October 5, 2015 at 9:24:09 PM UTC+2, szemrany wrote:
> Działa, używam go. Cała "magia" jest w znaczniku Carry, który jest
> wykorzystywany przez rozkaz RCL i wędruje z bajtu do bajtu.
Bez względu na to, czy Twój kod poprawnie wykorzystuje flagę
przeniesienia, czy też nie, odświeżę temat braku tego typu flag w
językach wysokiego poziomu. Tak łatwo by się programowało:
lo_word <<= 4;
hi_word = (hi_word <<= 4) | carry_bits;
Pozdrawiam
-
12. Data: 2015-10-06 01:09:20
Temat: Re: asm - przesuwanie wektora bajtow
Od: Waldek Hebisch <h...@a...uni.wroc.pl>
szemrany <s...@o...off> wrote:
> Witam
>
> Potrzebuj? przesun?? tablic?/wektor bajt?w w lewo o zadan? liczb? bit?w. Po
> jakim? tam czasie czytania i pr?b zrobi?em prock? opart? o instrukcj? RCL
> przesuwaj?ca o jeden bit:
>
>
> mov ebx, x // liczba bajt?w w wektorze
> mov eax, end_byte // adres ostatniego elementu
> clc
> @@loop:
> mov cl, byte ptr [eax]
> rcl cl, 1
> mov byte ptr [eax], CL
> dec eax
> dec ebx
> jne @@loop
>
> Teraz, gdy chc? przesun?? o 3 bity to wykonuj? ten kod w p?tli trzy razy.
>
> Czy ten kod mo?na zoptymalizowa? bardziej?
> Czy mo?na to zrobi? inaczej, bez RCL?
>
Napisz w C (niekompletne i nieprzetestowane):
carry = 0
for(i = 0; i < n; i++) {
val = *src++;
*dst++ = val<<k | carry;
carry = val>>(M-k);
}
gdzie val i carry sa odpowidniego typu bez znaku, M to ilosc bitow
w tym typie, n to ilosc jednostek do przesuniecia, k to i ile bitow
przesuwamy. Jesli jednostka jest bajt to przy przesuwaniu o jeden
bit ta twoja petla ma szanse byc szybsza (ale RCL to powolna
intrukcja...). Przy przesuwaniu w wiecej niz jeden bit metoda
z dwoma przesunieciami bedzie szybsza. To wyzej moze pracowac
na wiekszych jednostkach, np. po 64 bity. Ta sama metoda
uzywajac SSE pozwala przerobic 128 bitow na krok. Oczywiscie
wtedy jest problem z wyrownywaniem (podzielnoscia adresow
przez 8 czy 16) i koncowka. Ale jak masz dluzsze ciagi to
sie oplaca. Jesli masz troche luzu w pamieci to naprosciej
od razu dzialac na ciagach odpowiednio dlugich slow.
Jeszcze jedno: jak przesuwasz o 0 bitow to ten kod wyzej ma
prawo nie dzialac, po prostu wtedy nalezy kopiowac.
P.S. Jesli koniecznie chcesz w asm, to kompilator Ci powie
jak to wyglada, zreszta recznie tez latwo przetlumaczyc.
--
Waldek Hebisch
-
13. Data: 2015-10-06 06:55:45
Temat: Re: asm - przesuwanie wektora bajtow
Od: slawek <f...@f...com>
On Mon, 5 Oct 2015 21:23:45 +0200, szemrany <s...@o...off>
wrote:
> Tak naprawdę sens ma przesuwanie o 1 do 7 bitów, powyżej tego można
już
Ale z przesuwaniem w prawo aby przesunąć w lewo to od 1 do 3.
-
14. Data: 2015-10-06 10:26:55
Temat: Re: asm - przesuwanie wektora bajtow
Od: "Radoslaw Szwed" <r...@p...fm>
Użytkownik "szemrany" <s...@o...off> napisał w wiadomości
news:a6cvewd1yimk$.1h0av09ee1pjl$.dlg@40tude.net...
> Witam
>
> Potrzebuję przesunąć tablicę/wektor bajtów w lewo o zadaną liczbę bitów. Po
> jakimś tam czasie czytania i prób zrobiłem prockę opartą o instrukcję RCL
> przesuwająca o jeden bit:
>
>
> mov ebx, x // liczba bajtów w wektorze
> mov eax, end_byte // adres ostatniego elementu
> clc
> @@loop:
> mov cl, byte ptr [eax]
> rcl cl, 1
> mov byte ptr [eax], CL
> dec eax
> dec ebx
> jne @@loop
>
> Teraz, gdy chcę przesunąć o 3 bity to wykonuję ten kod w pętli trzy razy.
>
> Czy ten kod można zoptymalizować bardziej?
> Czy można to zrobić inaczej, bez RCL?
Zrobione inaczej bez RCL. Proszę sprawdzić powinna działać prawidłowo nie zdążyłem
przetestować
(skończyła się przerwa śniadaniowa :). Przesuwa od 1 do 8 bitów.
start:
mov ebx, 8 ; przesuwamy o 3 bity (2^3)
mov edi, 4 ; dlugsc wektora 4 bajty
mov esi, offset y ; adres wektora
xor ecx, ecx
next:
xor eax, eax
mov al, byte ptr [esi]
mul ebx
or al, cl
mov byte ptr [esi], al
mov cl, ah
inc esi
dec edi
jne next
Jest wolniejsza w porównaniu z poprzednia jeżeli przesuwamy o 1 bit w innym przypadku
jest szybsza.
-
15. Data: 2015-10-06 12:06:11
Temat: Re: asm - przesuwanie wektora bajtow
Od: "M.M." <m...@g...com>
On Tuesday, October 6, 2015 at 1:09:23 AM UTC+2, Waldek Hebisch wrote:
> szemrany wrote:
> > Witam
> >
> > Potrzebuj? przesun?? tablic?/wektor bajt?w w lewo o zadan? liczb? bit?w. Po
> > jakim? tam czasie czytania i pr?b zrobi?em prock? opart? o instrukcj? RCL
> > przesuwaj?ca o jeden bit:
> >
> >
> > mov ebx, x // liczba bajt?w w wektorze
> > mov eax, end_byte // adres ostatniego elementu
> > clc
> > @@loop:
> > mov cl, byte ptr [eax]
> > rcl cl, 1
> > mov byte ptr [eax], CL
> > dec eax
> > dec ebx
> > jne @@loop
> >
> > Teraz, gdy chc? przesun?? o 3 bity to wykonuj? ten kod w p?tli trzy razy.
> >
> > Czy ten kod mo?na zoptymalizowa? bardziej?
> > Czy mo?na to zrobi? inaczej, bez RCL?
> >
>
> Napisz w C (niekompletne i nieprzetestowane):
>
> carry = 0
> for(i = 0; i < n; i++) {
> val = *src++;
> *dst++ = val<<k | carry;
> carry = val>>(M-k);
> }
>
> gdzie val i carry sa odpowidniego typu bez znaku, M to ilosc bitow
> [...]
> jak to wyglada, zreszta recznie tez latwo przetlumaczyc.
Na moje tak (też nie kompilowałem):
if( x < 0 || x > 64 ) abort();
if( sizeof(tab[0]) != 8 ) abort();
for( i=n-1 ; i>=0 ; i-- ) {
tab[i] <<= x;
if( i > 0 )
tab[i] |= przesun_na_najmlodsze( najstarsze_bity( tab[i-1] , x ) );
}