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.