4.8.1. Загрузка и запись

Листинг ассемблера на Фиг. 4.22 показывает различные строковые команды. Загрузка строки LODS и запись строки STOS являются простейшими строковыми командами. Если программа указывает байтовый операнд в команде LODS, то она загружает в регистр AL байт, на который указывает пара регистров DS:SI. Затем она изменяет регистр SI на единицу; он увеличивается, либо уменьшается, в зависимости от состояния флага направления. Если команда LODS указывает на слово, то она загружает регистр AX и изменяет регистр SI на 2. Команда STOS строго противоположна, и записывает байт из регистра AL либо слово из регистра AX в ячейку памяти. В случае записи ячейка определяется парой регистров ES:DI. Команда записи изменяет регистр DI либо на единицу, либо на 2, в зависимости от типа операнда.

Программист может писать на ассемблере команду LODS (а также и все другие строковые команды) различными способами. Тип операнда можно указать частью кода операции, либо ассемдлер может определить тип элемента строки, основываясь на операнде, присутствующем в команде. Как показано на Фиг. 4.22, команда

LODS EXBYTE

порождает команду загрузки строк байтов, так же как и команда LODSB.


Microsoft (R) Macro Assembler Version 5.00                1/1/80 04:00:49
Фиг. 4.22 Команды обработки строк                               Page  1-1
                         PAGE     ,132
                         TITLE    Фиг. 4.22 Команды обработки строк
0000                     CODE     SEGMENT
                         ASSUME   CS:CODE,DS:CODE,ES:CODE
0000                     EXBYTE   LABEL     BYTE
0000                     EXWORD   LABEL     WORD
0000                     EXBYTE1  LABEL     BYTE
0000                     EXWORD1  LABEL     WORD
0000    AC                        LODS      EXBYTE      ; Загрузка AL из DS:SI
0001    AD                        LODS      EXWORD      ; Загрузка AX из DS:SI
0002    AC                        LODSB                 ; Загрузка AL из DS:SI
0003    AA                        STOS      EXBYTE      ; Сохранение AL в ES:DI
0004    AB                        STOS      EXWORD      ; Сохранение AX в ES:DI
0005    AB                        STOSW                 ; Сохранение AX в ES:DI
0006    F3/ AA                    REP       STOSB       ; Сохранение AL в ES:DI в цикле CX раз
0008    A4                        MOVS      EXBYTE1, EXBYTE ; Пересылка байта [ES:DI] <- [DS:SI]
0009    A5                        MOVS      EXWORD1, EXWORD ; Пересылка слова [ES:DI] <- [DS:SI]
000A    A4                        MOVSB                 ; Пересылка байта [ES:DI] <- [DS:SI]
000B    F3/ A5                    REP       MOVSW       ; Пересылка CX слов [ES:DI] <- [DS:SI]
000D    AE                        SCAS      EXBYTE1     ; Сравнение AL с [ES:DI]
000E    F3/ AE                    REPE      SCASB       ; Сравнение AL с [ES:DI] пока равно
0010    F2/ AF                    REPNE     SCASW       ; Сравнение AX с [ES:DI] пока не равно
0012    A7                        CMPS      EXWORD, EXWORD1 ; Сравнение слова [DS:SI] с [ES:DI]
0013    F3/ A7                    REPE      CMPSW       ; Сравнение слов [DS:SI] с [ES:DI] пока
                                                        ; равно в цикле CX раз
0015    F2/ A6                    REPNE     CMPSB       ; Сравнение байт [DS:SI] с [ES:DI] пока
                                                        ; не равно в цикле CX раз
0017                     CODE     ENDS
                         END

                                  Фиг.4.22 Строковые команды


В первом случае ассемблер определяет, что строка состоит из байта, поскольку EXBYTE - переменная типа BYTE. Во втором случае программист непосредственно указывает, что работает с байтами. Собственно ассемблер не требует поля операнда. Программисты чаще используют вторую форму, так как не имеют имени переменной, связанной со строкой. Программа динамически располагает строку в памяти, для нее не существует фиксированного места, и, следовательно, нет и имени переменной. Команда STOS аналогична. Чтобы непосредственно указать строку слов, а не байтов, используются коды операций LODSW и STOSW. Ассемблер должен знать, для байтовой строки или строки слов написана команда, поскольку машинные команды различны для различных типов строк. Эта разница определяет значение, на которое надо изменить индексный регистр.

Операнд в команде должен быть указан в том случае, если в программе используются основные формы команд LODS и STOS. Если программа не имеет удобной метки для строки, она может использовать формы LODSB и STOSB. Преимущество использования основной формы LODS и указания операнда заключается в том, что ассемблер при этом проверяет не только тип операнда, но и возможность его адресации. Так как команда LODS работает с объектами только в сегменте DS, оператор ASSUME должен соответственно описывать расположение сегмента поименованной переменной. Аналогично, ассемблер проверяет основную форму команды STOS на адресацию сегмента ES. Любая форма приемлема для ассемблера, но лучше использовать основную форму, чтобы позволить ассемблеру наилучшим способом проверить наличие ошибок в программе до выполнения.