Главная · Поиск книг · Поступления книг · 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 ... 36 37 38 39 40 41 42  43 44 45 46 47 48 49 ... 85
               .  .  .  .  .  .  .  .  .  .  .  .  .  .  .  .
               F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF

     Как было показано еще на рис.8.1,  отображение ASCII-символов, oсобых
проблем не вызывает. Что же касается отображения шест. значений в символах
ASCII, то этот процесс более сложный. Например, для вывода на экран в коде
ASCII  шест.00,  01  и т.д.  необходимо преобразовать шест.00 в шест.3030,
шест.01 в шест.3031 и т.д.
     В программе начальное значение поля HEXCTR  равно  00.  Это  значение
последовательно увеличивается  на  1.  Процедура  C10HEX  расщепляет  байт
HEXCTR на две щест.  цифры. Предположим, что байт HEXCTR содержит шест.4F.
Процедура сначала выделяет шест.  цифру 4 и использует  это  значение  для
перекодировки   по   таблице  XLATAB.  В  регистре  AL  устанавливается  в
результате значение шест.34. Затем процедура выделяет вторую шест. цифру F
и перекодирует ее в шест.46.  В результате oбработки получается шест.3446,
что отображается на экране как 4F.
     Так как функция DOS  для  вывода  на  экран  (шест.40)  рассматривает
шест.1A как конец файла, то в программе это значение заменяется на пробел.
Программа, использующая для вывода на экран функцию DOS (шест.09),  должна
заменять символ ограничитель '$' на пробел.
     Существует много  различных  способов  преобразования  шест.  цифр  в
ASCII-символы. Можно поэкспериментировать с операциями сдвига и сравнения.


     ПРОГРАММА: СОРТИРОВКА ЭЛЕМЕНТОВ ТАБЛИЦЫ
     ________________________________________________________________

     Часто  возникает  необходимость  сортировки  элементов   таблицы    в
восходящем  или  нисходящем  порядке.   Например,    пользователю    может
потребоваться список наименований товара в алфавитном порядке  или  список
общих цен в нисходящей последовательности.  Обычно,  табличные  данные  не
определяются как в предыдущей программе, а загружаются с клавиатуры или  с
диска.  Данный раздел посвящен сортировке элементов таблицы, что  касается
различных применений, включающих сортировку записей на  дисках,  то  здесь
возможны более сложные программы.
     Существует несколько алгоритмов сортировки таблиц  от  неэффективных,
но  понятных,  до  эффективных  и  непонятных.    Программа    сортировки,
предлагаемая в данном разделе, весьма эффективна и может  применяться  для
большинства табличных сортировок.  Конечно, если  не  проверить  различные
алгоритмы  сортировок,  то  даже  самая  неэффективная  программа    может
показаться работающей со скоростью света.  Но цель данной книги - показать
технику  ассемблера,  а  не  сортировки.  Основной  подход  заключается  в
сравнении соседних элементов таблицы.  Если первый элемент больше второго,
то  элементы  меняются  местами.  Таким  образом  выполняется    сравнение
элементов 1 со 2, 2 с 3 и т.д. до конца таблицы с перестановкой  элементов
там, где это необходимо. Если в проходе были сделаны перестановки, то весь
процесс повторяется с начала таблицы т.е. сравниваются снова элементы 1-2,
2-3 и т.д. Если в проходе не было перестановок, то таблица отсортирована и
можно прекратить процесс.
     Ниже  приведен  алгоритм,  в  котором  переменная    SWAP    является
индикатором: была перестановка элементов (YES) или нет (NO):

          G10:   Определить адрес последнего элемента
          G20:   Установить SWAP=NO
                 Определить адрес первого элемента
          G30:   Элемент > следующего элемента?
                      Да:  Представить элементы
                          Установить SWAP=YES
                 Перейти к следующему элементу
                 Конец таблицы?
                      Нет: Перейти на G30
                      Да:  SWAP=YES?
                           Да:  Перейти на G20 (повторить сорт.)
                           Нет: Конец сортировки

     Программа, показанная на рис.14.6, обеспечивает ввод с клавиатуры  до
30 имен, сортировку введенных имен в алфавитном порядке и вывод  на  экран
отсортированного списка имен.

__________________________________________________________________________

        page    60,132
TITLE   NMSORT  (EXE) Ввод и сортировка имен
; -----------------------------------------------
STACK   SGMENT  PARA STACK 'Stack'
        DW      32 DUP(?)
STACK   ENDS
; -----------------------------------------------
DATASG  SEGMENT PARA 'Data'
NAMEPAR LABEL   BYTE            ;Имя списка параметров:
MAXNLEN DB      21              ; макс. длина
NAMELEN DB      ?               ; число введенных символов
NAMEFLD DB      21 DUP(' ')     ; имя

CRLF    DB      13, 10, '$'
ENDADDR DW      ?
MESSG1  DB      'Name?', '$'
NAMECTR DB      00
NAMETAB DB      30 DUP(20 DUP(' ')) ;Таблица имен
NAMESAV DB      20 DUP(?), 13, 10, '$'
SWAPPED DB      00
DATA    ENDS
; -----------------------------------------------
CODESG  SEGMENT PARA 'Code'
BEGIN   PROC    FAR
        ASSUME CS:CODESG,DS:DATDSG,SS:STACK,ES:DATASG
        PUSH    DS
        SUB     AX,AX
        PUSH    AX
        MOV     AX,DATASG
        MOV     DS,AX
        MOV     ES,AX
        CLD
        LEA     DI,NAMETAB
        CALL    Q10CLR          ;Очистить экран
        CALL    Q20CURS         ;Установить курсор
A20LOOP:
        CALL    B10READ         ;Ввести имя с клавиатуры
        CMP     NAMELEN,00      ;Есть ли еще имена?
        JZ      A30             ; нет - идти на сортировку
        CMP     NAMECTR,30      ;Введено 30 имен?
        JE      A30             ; да - идти на сортировку
        CALL    D10STOR         ;Записать имя в таблицу
        JMP     A20LOOP
A30:                            ;Конец ввода имен
        CALL    Q10CLR          ;Очистить экран
        CALL    Q20CURS         ; и установить курсор
        CMP     NAMECTR,01      ;Введено менее 2 имен?
        JBE     A40             ; да - выйти
        CALL    G10SORT         ;Сортировать имена
        CALL    K10DISP         ;Вывести результат на экран
A40:    RET                     ;Завершить программу
BEGIN   ENDP
;               Ввод имен с клавиатуры?
;               ----------------------
B10READ PROC
        MOV     AH,09
        LEA     DX,MESSG1       ;Вывести текст запроса
        INT     21H
        MOV     AH,0AH
        LEA     DX,NAMEPAR      ;Ввести имя
        INT     21H
        MOV     AH,09
        LEA     DX,CRLF         ;Вывести CRLF
        INT     21H

        MOV     BH,00           ;Очистить поле после имени
        MOV     BL,NAMELEN      ;Получить счетчик символов
        MOV     CX,21
        SUB     CX,BX           ;Вычислить оставшуюся длину
B20:
        MOV     NAMEFLD[BX],20H ;Установить символ пробела
        INC     BX
        LOOP    B20
        RET
B10READ ENDP
;               Запись имени в таблицу:
;               ----------------------
D10STOR PROC
        INC     NAMECTR         ;Число имен в таблице
        CLD
        LES     SI,NAMEFLD
        MOV     CX,10
        REP MOVSV               ;Переслать имя в таблицу
        RET
D10STOR ENDP
;               Сортировка имен в таблице:
;               -------------------------
G10SORT PROC
        SUB     DI,40           ;Установить адреса останова
        MOV     ENDADDR,DI
G20:
        MOV     SWAPPED,00      ;Установить начало
        LEA     SI,NAMETAB      ; таблицы
G30:
        MOV     CX,20           ;Длина сравнения
        MOV     DI,SI
        ADD     DI,20           ;Следующее имя для сравнения
        MOV     AX,DI
        MOV     BX,SI
        REPE CMPSB              ;Сравнить имя со следующим
        JBE     G40             ; нет перестановки
        CALL    H10XCHG         ; перестановка
G40:
        MOV     SI,AX
        CMP     SI,ENDADDR      ;Конец таблицы?
        JBE     G30             ; нет - продолжить
        CMP     SWAPPED,00      ;Есть перестановки?
        JNZ     G20             ; да - продолжить,
        RET                     ; нет - конец сортировки
G10SORT ENDP
;               Перестановка элементов таблицы:
;               ------------------------------
H10XCHG PROC
        MOV     CX,10
        LEA     DI,NAMESAV
        MOV     SI,BX
        REP MOVSW               ;Сохранить меньший элемент

        MOV     CX,10
        MOV     DI,BX
        REP MOVSW               ;Переслать больший элемент
                                ; на место меньшего
        MOV     CX,10
        LEA     SI,NAMESAV
        REP MOVSW               ;Переслать сохраненный
                                ; элемент на место большего
        MOV     SWAPPED,01      ;Признак перестановки
        RET
H10XCHG ENDP
;               Вывод на экран отсортированные имена:
;               ------------------------------------
K10DISP PROC
        LEA     SI,NAMETAB
K20:
        LEA     DI,NAMESAV      ;Начальный адрес таблицы
        MOV     CX,10
        REP MOVSV
        MOV     AH,09
        LEA     DX,NAMESAV
        INT     21H             ;Вывести на экран
        DEC     NAMECTR         ;Это последний элемент?
        JNZ     K20             ; нет - повторить цикл,
        RET                     ; да - выйти
K10DISP ENDP
;               Очистка экрана:
;               --------------
Q10CLR  PROC
        MOV     AX,0600H
        MOV     BH,61H          ;Цвет (07 для ч/б)
        SUB     CX,CX
        MOV     DX,184FH
        INT     10H
        RET
Q10CLR  ENDP
;               Установка курсора:
;               -----------------
Q20CURS PROC
        MOV     AH,02
        SUB     BH,BH
        SUB     DX,DX           ;Установить курсор в 00,00
        INT     10H
        RET
Q20CURS ENDP

CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.14.6. Сортировка таблицы имен


     ОПЕРАТОРЫ ТИПА, ДЛИНА И РАЗМЕРА
     ________________________________________________________________

     Ассемблер  содержит  ряд  специальных  операторов,   которые    могут
оказаться полезными при программировании.  Например, при  изменении  длины
таблицы придется модифицировать программу (для нового определения таблицы)
и процедуры,  проверяющие  конец  таблицы.  В  этом  случае  использование
операторов TYPE (тип), LENGTH (длина) и SIZE (размер) позволяют  уменьшить
число модифицируемых команд.
     Рассмотрим определение следующей таблицы из десяти слов:

               TABLEX    DW   10 DUP(?) ;Таблица из 10 слов

Программа может использовать оператор TYPE  для  определения  типа  (DW  в
данном  случае),  оператор  LENGTH  для  определения  DUP-фактора  (10)  и
оператор SIZE для определения числа  байтов  (10  х  2  =  20).  Следующие
команды иллюстрируют три таких применения:

               MOV  AX,TYPE TABLEX      ;AX=0002
               MOV  BX,LENGTH TABLEX    ;BX=000A  (10)
               MOV  CX,SIZE TABLEX      ;CX=0014  (20)

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

               CMP  SI,SIZE TABLEX

     В главе 23 "Справочник по  директивам  ассемблера"  дается  детальное
описание операторов TYPE, LENGTH и SIZE.


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

     - Для    большинства   применений,   определяйте   таблицы,   имеющие
родственные элементы одной длины и формата данных.

     - Стройте таблицы на основе форматов данных. Например, элементы могут
быть символьные или числовые длиной один, два и более байтов каждый. Может
оказаться более практичным определение двух таблиц:  одна,  например,  для
трехсимвольных  значений  номеpов,  а другая для двухбайтовых значений цен
единиц товара.  В процессе поиска адрес элементов таблицы  номеров  должен
Предыдущая страница Следующая страница
1 ... 36 37 38 39 40 41 42  43 44 45 46 47 48 49 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама