[Asm] Konwersja na inny jezyk...

0

Witam!

Mam wielki problem z pewna biblioteka. Obsluguje ona dzialania na dowolnie duzych liczbach, tyle ze ograniczonych 255 znakami. Potrzebuje zwiekszyc ten limit(a raczej go zlikwidowac) ale niestety nie rozumiem ASM-a na tyle zeby ten kod przerobic samemu... Moj kod ciagle sie sypie i w koncu odpuscilem.

Nie rozumiem dzialania intrukcji rep, movsb,stosb,lodsb. Czym to zastapic ?

http://pastebin.com/m240bb395 tutaj zamieszczam caly unit pisany w Pascalu. Chodzi mi glownie o funkcje Add/Sub/Mul/Diviz. Jezyk nie ma znaczenia, znacznie latwiej mi jest przepisac kod z np. C.

Jesli ktos nie ma czasu i checi to chociaz prosze o naprowadzenie mnie na dobry trop.

0

Co do instrukcji asm-a to:
rep inst - powtarza instrukcje inst dopóki rejestr CX jest różny od zera. rep ma też postaci repe/repz i repne/repnz, które działają aż do (odpowiednio) ustawienia lub wyzerowanie znacznika CF

movsb - przesyła bajt spod adresu DS:[SI] do bajtu spod adresu ES:[DI] oraz zwiększa (jeżeli znacznik DF jest wyzerowany) lub zmniejsza (jeżeli DF=0) wartości rejestrów SI oraz DI

stosb - przesyła zawartość rejestru AL do bajtu spod ES:[DI] i (jak w movsb) zmienia wartość rejestru DI

lodsb - przesyła bajt spod adresu DS:[SI] do rejestru AL i (jak w movsb) zmienia wartość rejestru SI

Istnieją jeszcze dodatkowe formy movsb/stosb/lodsb:
movsw/stosw/lodsw - działają na słowach (2 bajty) i (w stosw/lodsw) na rejestrze AX
movsd/stosd/lodsd - działają na słowach podwójnych (4 bajty), rejestrach ESI i EDI (zamiast SI i DI) oraz (w stosd/lodsd) na rejestrze EAX

Co do możliwości ich zastąpienia:
Wszystko można (w asm-ie) zastąpić odpowiednimi instrukcjami mov (i ewentualnie push/pop):
movsb:
push ax
mov al, byte ptr ds:[si]
mov byte ptr es:[di], al
pop ax

stosb:
mov byte ptr es:[di], al

lodsb:
mov al, byte ptr ds:[si]

W językach wysokopoziomowych (Pascal, C, C++ itp.) movsb jest zwykłym przypisaniem wartości bajtu między dwiema zmiennymi: (przykład w C++)

char zm1, zm2;
zm1 = zm2; //<-- to w asm-ie może być zastąpione przez movsb

Z stosb i lodsb jest już gorzej ponieważ nie mają one bezpośredniego odwzorowania w "wyższych" językach. Związane jest to ze względną niedostępnością rejestrów procesora z poziomu składni języka "wysokiego". W C++ istnieje modyfikator zmiennych register, który powoduje, że wartość danej zmiennej jest zawsze przechowywana w rejestrze procesora zamiast w pamięci. Wtedy (zakładając, że nasza zmienna register będzie w rejestrze AL) można by napisać przykład:

register char zm1;
char zm2;

zm2 = zm1; //to by było zrobione przez stosb
zm1 = zm2; //a to przez lodsb

W innych językach też istnieje tworzenie zmiennych-rejestrów ale to już sam możesz poszukać :-)

0

Istnieją jeszcze dodatkowe formy movsb/stosb/lodsb:
movsw/stosw/lodsw - działają na słowach (2 bajty) i (w stosw/lodsw) na rejestrze AX
movsd/stosd/lodsd - działają na słowach podwójnych (4 bajty), rejestrach ESI i EDI (zamiast SI i DI) oraz (w stosd/lodsd) na rejestrze EAX

Błąd. To czy movsb, movsd, itd używają (esi, edi) czy (si, di) zależy od trybu (16, 32 bit) i czy są poprzedzone prefixem 0x66, który zmienia traktowanie instrukcji (z 16 na 32 bit lub odwrotnie). W trybie 32 bitowym wszystkie instrukcje typu movs, lods czy stos bez prefixów używają do adresowania rejestrów edi, esi.

movsd: destination[destinationIndex++] = source[sourceIndex++] // dla CF = 0
lodsd: eax = source[sourceIndex++]
stosd: destination[destinationIndex++] = eax
rep = while (ecx--) { następna_instrukcja } // jakoś tak, nie pamiętam dokładnie

1 użytkowników online, w tym zalogowanych: 0, gości: 1