Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
Demon's Souls |#13| Storm King
Demon's Souls |#12| Old Monk & Old Hero
Demon's Souls |#11| Мaneater part 2
Demon's Souls |#10| Мaneater (part 1)

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Питер Абель Весь текст 992.61 Kb

Ассемблер и программирование для IBM PC

Предыдущая страница Следующая страница
1 ... 25 26 27 28 29 30 31  32 33 34 35 36 37 38 ... 85
сравнении строк, которые содержат числовые данные, определенные как DW, DD
или DQ.


     SCAS: СКАНИРОВАНИЕ СТРОК
     ________________________________________________________________

     Команда  SCAS  отличается  от  команды  CMPS  тем,   что    сканирует
(просматривает) строку на определенное значение байта или  слова.  Команда
SCAS сравнивает содержимое области памяти (адресуемой pегистрами ES:DI)  с
содержимым регистра AL или AX.  В зависимости от значения флага DF команда
SCAS также увеличивает или уменьшает адрес в регистре DI на  1  для  байта
или на 2 для слова.  Команда SCAS устанавливает флаги AF, CF, OF, PF, SF и
ZF.  При использовании префикса REP и значения длины в регистре CX команда
SCAS может сканировать строки любой длины.
     Команда SCAS особенно полезна, например, в текстовых редакторах,  где
программа должна сканировать строки,  выполняя  поиск  знаков  пунктуации:
точек, запятых и пробелов.
     На рис.11.1 процедура H10SCAS сканирует  область  NAME1  на  строчную
букву "m".  Так как команда SCASB  должна  продолжать  сканирование,  пока
результат сравнения -  "не  равно"  или  регистр  CX  не  равен  нулю,  то
используется префикс REPNE:

               REPNE SCASB

     Так как область NAME1 содержит слово "Assemblers", то  команда  SCASB
находит символ "m" в пятом сравнении.  При использовании  отладчика  DEBUG
для трассировки команд в конце процедуры H10SCAS можно увидеть в  регистре
AH значение 03 для индикации того, что  символ  "m"  найден.  Команда  REP
SCASB кроме того уменьшит значение регистра CX от 10 до 06.
     Команда SCASW сканирует в памяти слово  на  соответствие  значению  в
регистре AX.  При использовании команд LODSW или MOV для пересылки слова в
регистр AX, следует помнить, что первый байт будет в регистре AL, а второй
байт - в регистре AH.  Так как команда SCAS сравнивает  байты  в  обратной
последовательности, то oперация корректна.


     СКАНИРОВАНИЕ И ЗАМЕНА
     ________________________________________________________________

     В  процессе  обработки  текстовой   информации    может    возникнуть
необходимость замены определенных символов в тексте на  другие,  например,
подстановка  пробелов  вместо  различных   редактирующих    символов.    В
приведенном ниже фрагменте программы  осуществляется  сканирование  cтроки
STRING и замена символа амперсанд (&) на  символ  пробела.  Когда  команда
SCASB обнаружит символ &  (в  примере  это  будет  позиция  STRING+8),  то
операция сканирования прекратится  и  регистр  DI  будет  содержать  aдрес
STRING+9. Для получения адреса символа & необходимо  уменьшить  содержимое
DI на единицу и записать по полученному адресу символ пробела.

               STRLEN    EQU  15             ;Длина поля STRING
               STRING    DB   'The time&is now'
                         ...
                         CLD
                         MOV  AL,'&'         ;Искомый символ
                         MOV  CX,STRLEN      ;Длина поля STRING
                         LEA  DI,STRING      ;Адрес поля STRING
                         REPNE SCASB         ;Сканировать
                         JNZ  K20            ;Символ найден?
                         DEC  DI             ;Да - уменьшить адрес
                         MOV  BYTE PTR[DI],20H  ;Подставить пробел
               K20:      RET


     АЛЬТЕРНАТИВНОЕ КОДИРОВАНИЕ
     ________________________________________________________________

     При использовании  команд  MOVSB  или  MOVSW  ассемблер  предполагает
наличие  корректной  длины  строковых  данных  и  не  требует  кодирования
операндов в команде.  Для команды MOVS длина должна  быть  закодирована  в
операндах.  Например, если поля FLDA и FLDB определены как байтовые  (DB),
то команда
               REP  MOVS FLDA,FLDB

предполагает повторяющуюся пересылку байтов из поля FLDB в поле FLDA.  Эту
команду можно записать также в следующем виде:

               REP  MOVS ES:BYTE PTR[DI],DS:[SI]

Однако загрузка регистров DI и SI адресами FLDA и FLDB oбязательна в любом
случае.


     ДУБЛИРОВАНИЕ ОБРАЗЦА
     ________________________________________________________________

     Команда  STOS  бывает  полезна  для  установки  в  некоторой  области
oпределенных значений байтов  и  слов.  Для  дублирования  образца,  длина
которого  превышает  размер  слова,  можно  использовать  команду  MOVS  с
небольшой модификацией.  Предположим, что необходимо  сформировать  строку
следующего вида:

               ***---***---***---***---***--- . . .

Вместо того, чтобы  определять  полностью  всю  строку,  можно  определить
только первые  шесть  байтов.  Закодируем  образец  непосредственно  перед
обрабатываемой строкой следующим образом:

               PATTERN   DB   '***---'
               DISAREA   DB   42 DUP(?)
                         .
                         .
                         CLD
                         MOV  CX,21
                         LEA  DI,DISAREA
                         LEA  SI,PATTERN
                         REP MOVSW

В процессе выполнения команда MOVSW сначала пересылает первое  слово  (**)
из образца PATTERN в первое слово области DISAREA, затем  -  второе  слово
(*-), потом третье (--):

                    ***---***---
                    |     |
               PATTERN   DISAREA

К этому моменту регистр DI будет содержать адрес DISAREA+6, а pегистр SI -
PATTERN+6, который также является адресом  DISAREA.  Затем  команда  MOVSW
автоматически дублирует образец,  пересылая  первое  слово  из  DISAREA  в
DISAREA+6, из DISAREA+2, в DISAREA+8, из DISAREA+4 в DISAREA+10 и  т.д.  В
результате образец будет полностью продублирован по всей области DISAREA:

                    ***---***---***---***---***--- . . . ***---
                    |           |           |            |
               PATTERN      DISAREA+6   DISAREA+12   DISAREA+42

     Данную технику можно использовать для дублирования в  области  памяти
любого образца любой длины. Образец должен быть расположен непосредственно
перед принимающей областью.


     ПРОГРАММА: ВЫРАВНИВАНИЕ ВПРАВО ПРИ ВЫВОДЕ НА ЭКРАН
     ________________________________________________________________

     COM-программа, изображенная  на  рис.11.2,  иллюстрирует  почти  весь
материал,  приведенный  в  этой  главе.  Процедуры  программы    выполняют
следующие действия:

B10INPT - Принимает имена длиной до 30 символов, вводимых вверху экрана.
D10SCAS - Использует команду SCASB для сканирования имен и об хода  любого
          ввода, содержащего символ "звездочка".
E10RGHT - Использует команду MOVSB для выравнивания имен по правой границе
          выводит имена  в  колонку  в  правой части экрана.  Длина в поле
          ACTNLEN из списка параметров ввода используется  для  вычисления
          самого правого символа в имени, например:

                               JEROME KERN
                         OSCAR HAMMERSTEIN
                            RICHARD ROGERS

F10CLNM - Использует команду STOSW для очистки области имени в памяти.

__________________________________________________________________________

        page    60,132
TITLE   EXRING  (COM) Вывод имен, выровненных справа
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG,ES:CODESG
        ORG     100H
BEGIN:  JMP     SHORT MAIN
;--------------------------------------------------------
NAMEPAR LABEL   BYTE            ;Имя списка параметров
MAXNLEN DB      31              ;Макс. длина
ACTNLEN DB      ?               ;Число введенных символов
NAMEFLD DB      31 DUP(' ')     ;Имя

PROMPT  DB      'Name?', '$'
NAMEDSP DB      31 DUP(' '), 13, 10, '$'
ROW     DB      00
;--------------------------------------------------------
MAIN    PROC    NEAR            ;Основная процедура
        MOV     AX,0600H
        CALL    Q10SCR          ;Очистить экран
        SUB     DX,DX           ;Установить курсор в 00,00
        CALL    Q20CURS
A10LOOP:
        CALL    B10INPT         ;Ввести имя с клавиатуры
        TEST    ACTNLEN,0FFH    ;Нет имени? (т.е. конец)
        JZ      A90             ; да - выйти
        CALL    D10SCAS         ;Найти звездочку
        CMP     AL,'*'          ;Найдена?
        JE      A10LOOP         ; да - обойти
        CALL    E10RGHT         ;Выровнять имя справа
        CALL    A10LOOP
A90:    RET
MAIN    ENDP
;               Вывод запроса для ввода имени:
;               -----------------------------
B10INPT PROC
        MOV     AH,09
        LEA     DX,PROMPT       ;Выдать текст запроса
        INT     21H
        RET
B10INPT ENDP
;               Поиск звездочки в имени:
;               -----------------------
D10SCAS PROC
        CLD
        MOV     AL,'*'
        MOV     CX,30           ;Длина сканирования - 30
        LEA     DI,NAMEFLD
        REPNE SCASB             ;Звездочка найдена?
        JE      D20             ; да - выйти,
        MOV     AL,20H          ; нет стереть * в AL
D20:    RET
D10SCAS ENDP
;               Выравнивание справа и вывод на экран:
;               ------------------------------------
E10RGHT PROC
        STD
        SUB     CH,CH
        MOV     CL,ACTNLEN      ;Длина в CX для REP
        LEA     SI,NAMEFLD      ;Вычислить самую правую
        ADD     SI,CX           ; позицию
        DEC     SI              ; введенного имени
        LEA     DI,NAMEDSP+30   ;Правая поз. поля имени
        REP MOVSB               ;Переслать справа налево
        MOV     DH,ROW
        MOV     DL,48
        CALL    Q20CURS         ;Установить курсор
        MOV     AH,09
        LEA     DX,NAMEDSP      ;Выдать имя на экран
        INT     21H
        CMP     ROW,20          ;Последняя строка экрана?
        JAE     E20             ; нет -
        INC     ROW             ; увеличить строку,
        JMP     E90
E20:
        MOV     AX,0601H        ; да -
        CALL    Q10SCR          ; прокрутить и
        MOV     DH,ROW          ; установить курсор
        MOV     DL,00
        CALL    Q20CURS
E90:    RET
E10RGHT ENDP
;               Очистить область имени:
;               ----------------------
F10CLNM PROC
        CLD
        MOV     AX,2020H
        MOV     CX,15           ;Очистить 15 слов
        LEA     DI,NAMEDSP
        REP STOSW
        RET
F10CLNM ENDP
;               Прокрутка экрана:
;               ----------------
Q10SCR  PROC                    ;AX установлен при вызове
        MOV     BH,30           ;Цвет ( 07 для ч/б)
        MOV     CX,00
        MOV     DX,184FH
        INT     10H
        RET
Q10SCR  ENDP
;               Установить курсор (строка/столбец):
;               ----------------------------------
Q20CURS PROC                    ;DX установлен при вызове
        MOV     AH,02
        SUB     BH,BH
        INT     10H
        RET
Q20CURS ENDP
CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.11.2. Выравнивание вправо при выводе на экран.


     ОСНОВНЫЕ ПОЛОЖЕНИЯ НА ПАМЯТЬ
     ________________________________________________________________

     - Для  цепочечных  команд  MOVS,  STOS,  CMPS  и  SCAS  не  забывайте
инициализировать регистр ES.

     - Сбрасывайте  (CLD)  или  устанавливайте  (STD)  флаг  направления в
соответствии с направлением обработки.

     - Не  забывайте  устанавливать  в  регистрах  DI  и  SI   необходимые
значения.  Например,  команда MOVS предполагает операнды DI,SI,  а команда
CMPS - SI,DI.

     - Инициализируйте регистр CX в соответствии с количеством байтов  или
слов, участвующих в процессе обработки.

     - Для  обычной  обработки  используйте  префикс REP для команд MOVS и
STOS и модифицированный префикс (REPE или REPNE) для команд CMPS и SCAS.

     - Помните об обратной последовательности байтов в сравниваемых cловах
Предыдущая страница Следующая страница
1 ... 25 26 27 28 29 30 31  32 33 34 35 36 37 38 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама