Montaż - ciągi
W naszych poprzednich przykładach używaliśmy już ciągów o zmiennej długości. Łańcuchy o zmiennej długości mogą mieć dowolną liczbę znaków. Ogólnie rzecz biorąc, określamy długość ciągu na jeden z dwóch sposobów -
- Jawne przechowywanie długości łańcucha
- Używanie znaku wartownika
Możemy jawnie przechowywać długość ciągu, używając symbolu licznika lokalizacji $, który reprezentuje bieżącą wartość licznika lokalizacji. W poniższym przykładzie -
msg db 'Hello, world!',0xa ;our dear string
len equ $ - msg ;length of our dear string
$ wskazuje bajt po ostatnim znaku zmiennej łańcuchowej msg . W związku z tym,$-msgpodaje długość sznurka. Możemy też pisać
msg db 'Hello, world!',0xa ;our dear string
len equ 13 ;length of our dear string
Alternatywnie można przechowywać ciągi z końcowym znakiem wartownika, aby oddzielić ciąg, zamiast jawnie przechowywać długość ciągu. Znak wartownika powinien być znakiem specjalnym, który nie występuje w ciągu.
Na przykład -
message DB 'I am loving it!', 0
Instrukcje dotyczące strun
Każda instrukcja łańcuchowa może wymagać operandu źródłowego, operandu docelowego lub obu. W przypadku segmentów 32-bitowych instrukcje łańcuchowe używają rejestrów ESI i EDI, aby wskazywać odpowiednio operandy źródłowe i docelowe.
Jednak w przypadku segmentów 16-bitowych rejestry SI i DI są używane do wskazywania odpowiednio źródła i celu.
Istnieje pięć podstawowych instrukcji dotyczących przetwarzania łańcuchów. Oni są -
MOVS - Ta instrukcja przenosi 1 bajt, słowo lub podwójne słowo danych z komórki pamięci do innej.
LODS- Ta instrukcja ładuje się z pamięci. Jeśli operand jest jednobajtowy, jest ładowany do rejestru AL, jeśli operand jest jednym słowem, jest ładowany do rejestru AX, a podwójne słowo jest ładowane do rejestru EAX.
STOS - Ta instrukcja przechowuje dane z rejestru (AL, AX lub EAX) do pamięci.
CMPS- Ta instrukcja porównuje dwa elementy danych w pamięci. Dane mogą mieć rozmiar bajtowy, słowo lub podwójne słowo.
SCAS - Ta instrukcja porównuje zawartość rejestru (AL, AX lub EAX) z zawartością pozycji w pamięci.
Każda z powyższych instrukcji ma wersję zawierającą bajty, słowo i podwójne słowo, a instrukcje łańcuchowe można powtórzyć, używając przedrostka powtórzenia.
Instrukcje te używają pary rejestrów ES: DI i DS: SI, gdzie rejestry DI i SI zawierają ważne adresy przesunięcia, które odnoszą się do bajtów przechowywanych w pamięci. SI jest zwykle skojarzona z DS (segmentem danych), a DI jest zawsze związana z ES (segment dodatkowy).
Rejestry DS: SI (lub ESI) i ES: DI (lub EDI) wskazują odpowiednio operandy źródłowe i docelowe. Zakłada się, że operand źródłowy znajduje się w DS: SI (lub ESI), a operand docelowy w ES: DI (lub EDI) w pamięci.
W przypadku adresów 16-bitowych używane są rejestry SI i DI, a w przypadku adresów 32-bitowych - rejestry ESI i EDI.
Poniższa tabela zawiera różne wersje instrukcji łańcuchowych i zakładaną przestrzeń operandów.
Podstawowa instrukcja | Operandy w | Operacja na bajtach | Operacja na słowie | Operacja podwójnego słowa |
---|---|---|---|---|
MOVS | ES: DI, DS: SI | MOVSB | MOVSW | MOVSD |
LODS | AX, DS: SI | LODSB | LODSW | LODSD |
STOS | ES: DI, AX | STOSB | STOSW | STOSD |
CMPS | DS: SI, ES: DI | CMPSB | CMPSW | CMPSD |
SCAS | ES: DI, AX | SCASB | SCASW | SCASD |
Prefiksy powtórzeń
Prefiks REP ustawiony przed instrukcją łańcuchową, na przykład - REP MOVSB, powoduje powtórzenie instrukcji w oparciu o licznik umieszczony w rejestrze CX. REP wykonuje instrukcję, zmniejsza CX o 1 i sprawdza, czy CX wynosi zero. Powtarza przetwarzanie instrukcji, aż wartość CX wynosi zero.
Flaga kierunku (DF) określa kierunek operacji.
- Użyj CLD (Clear Direction Flag, DF = 0), aby wykonać operację od lewej do prawej.
- Użyj STD (Ustaw flagę kierunku, DF = 1), aby wykonać operację od prawej do lewej.
Prefiks REP ma również następujące odmiany:
REP: To bezwarunkowa powtórka. Powtarza operację, aż wartość CX wynosi zero.
REPE lub REPZ: Jest to warunkowe powtórzenie. Powtarza operację, podczas gdy flaga zero wskazuje równość / zero. Zatrzymuje się, gdy ZF wskazuje, że nie jest równe / zero lub gdy CX wynosi zero.
REPNE lub REPNZ: Jest to również powtórzenie warunkowe. Powtarza operację, podczas gdy flaga zero wskazuje, że nie jest równa / zero. Zatrzymuje się, gdy ZF wskazuje równe / zero lub gdy wartość CX jest zmniejszana do zera.