Cel rejestrów ESI i EDI?


Odpowiedzi:


78

Jest kilka operacji, które możesz wykonać tylko z DI / SI (lub ich rozszerzonymi odpowiednikami, jeśli nie nauczyłeś się ASM w 1985). Wśród nich są

REP STOSB
REP MOVSB
REP SCASB

Które są odpowiednio operacjami wielokrotnego (= masy) przechowywania, ładowania i skanowania. To, co robisz, to konfigurowanie SI i / lub DI tak, aby wskazywały na jeden lub oba operandy, być może umieszcza licznik w CX, a następnie pozwala zgrać. Są to operacje, które działają na kilku bajtach naraz i powodują automatyczne przełączenie procesora. Ponieważ nie tworzysz jawnie pętli kodujących, one działają wydajniej (zwykle) niż pętle kodowane ręcznie.

Na wszelki wypadek, gdybyś się zastanawiał: w zależności od tego, jak ustawisz operację, wielokrotne zapisywanie może być czymś prostym, na przykład wstawieniem wartości 0 do dużego, ciągłego bloku pamięci; Myślę, że MOVSB ​​służy do kopiowania danych z jednego bufora (cóż, dowolnej paczki bajtów) do innego; a SCASB służy do szukania bajtu pasującego do jakiegoś kryterium wyszukiwania (nie jestem pewien, czy wyszukuje tylko według równości, czy co - możesz to sprawdzić :))

To większość tego, do czego służą te przepisy.


7
Wskazówka dotycząca optymalizacji z przeszłości: rep stosw jest znacznie szybszy niż rep stosb , więc jeśli kopiowanie dwóch i dwóch bajtów pasuje do tego, co próbujesz zrobić, użyj tego w ręcznie zoptymalizowanym 16-bitowym kodzie asemblera x86 ...
Alexander,

88

SI = Indeks źródłowy
DI = Indeks docelowy

Jak wskazywali inni, mają specjalne zastosowania w instrukcjach łańcuchowych. Do programowania trybu do rzeczywistego, ESrejestr segmentowy należy stosować DIi DSze SIjak w

movsb  es:di, ds:si

SI i DI mogą być również używane jako rejestry indeksowe ogólnego przeznaczenia. Na przykład Ckod źródłowy

srcp [srcidx++] = argv [j];

kompiluje się do

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

gdzie ebp+12zawiera argv, ebxjest ji edima srcidx. Zwróć uwagę, że trzecia instrukcja używa edipomnożenia przez 4 i dodaje ebpprzesunięcie o 0x54 (położenie srcp); nawiasy wokół adresu wskazują na kierunek pośredni.


Chociaż nie pamiętam, gdzie go widziałem, ale to potwierdza większość tego, a te (slajd 17) inne:

AX= akumulator = akumulator
DXpodwójnego słowa
CX= licznik
BX= rejestr podstawowy

Wyglądają jak rejestry ogólnego przeznaczenia, ale istnieje szereg instrukcji, które (nieoczekiwanie?) Używają jednej z nich - ale która? - w sposób jawny.


37

Kody operacyjne, takie jak MOVSB ​​i MOVSW, które skutecznie kopiują dane z pamięci wskazywanej przez ESI do pamięci wskazywanej przez EDI. A zatem,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

12

Oprócz operacji na łańcuchach (MOVS / INS / STOS / CMPS / SCASB / W / D / Q itp.) Wspomnianych w innych odpowiedziach, chciałem dodać, że istnieją również bardziej "nowoczesne" instrukcje asemblera x86, które domyślnie używają w najmniej EDI / RDI:

Instrukcja SSE2 MASKMOVDQU(i nadchodzące AVX VMASKMOVDQU) wybiórczo zapisuje bajty z rejestru XMM do pamięci wskazywanej przez EDI / RDI.


6

Oprócz rejestrów używanych do operacji masowych są one użyteczne ze względu na ich właściwość zachowania poprzez wywołanie funkcji (zachowane wywołanie) w 32-bitowej konwencji wywoływania. ESI, EDI, EBX, EBP, ESP są zachowywane, podczas gdy EAX, ECX i EDX nie są zachowywane. Rejestry zachowane przez wywołania są respektowane przez funkcję biblioteki C, a ich wartości są zachowywane przez wywołania funkcji biblioteki C.

Jeff Duntemann w swojej książce o języku asemblera ma przykład kodu asemblera do drukowania argumentów wiersza poleceń. Kod używa esi i edi do przechowywania liczników, ponieważ pozostaną one niezmienione przez funkcję printf z biblioteki C. W przypadku innych rejestrów, takich jak eax, ecx, edx, nie ma gwarancji, że nie będą one używane przez funkcje biblioteki C.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

Zobacz rozdział 12.8. Jak C widzi argumenty wiersza poleceń.

Zauważ, że 64-bitowe konwencje wywoływania różnią się od 32-bitowych konwencji wywoływania i nie jestem pewien, czy te rejestry są zachowywane, czy nie.


Nigdy nie słyszałem słowa „święty” używanego do opisania tego, co większość ludzi nazywa „niestabilnym” / „nieulotnym” lub „ocalony rozmówcą” kontra „zbawiony dzwoniącego”. Lubię „zachowane połączenia” / „zablokowane połączenia”, ponieważ nie oznacza to, że faktycznie są one zapisywane w dowolnym miejscu. W każdym razie ESI / RSI i EDI / RDI nie są zachowywane w ABI x86-64 System V.
Peter Cordes,

Zapomniałeś także wymienić EBP i ESP jako zachowane połączenia w typowych 32-bitowych konwencjach wywoływania.
Peter Cordes,

1
W każdym razie to całkiem dobry punkt. W rzeczywistym kodzie bardziej prawdopodobne jest, że wybierzesz EDI / ESI ze względu na przyczyny związane z konwencją wywoływania, niż z tego, że są one specjalne dla jakichkolwiek instrukcji.
Peter Cordes,

Lubię zachowywać połączenia. Zaktualizowałem odpowiedź tym samym. Dzięki za recenzję.
Jay Rajput,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.