Главная · Поиск книг · Поступления книг · 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 ... 30 31 32 33 34 35 36  37 38 39 40 41 42 43 ... 85

     12.1. Закодируйте команды для  сложения  а)  слова  DATAX  со  словом
DATAY; б) двойного слова, начинающегося по адресу DATAX, с двойным  словом
в DATAY.

     12.2. Объясните действие следующих команд:

               STC
               MOV BX,DATAX
               ADC BX,DATAY

     12.3. Закодируйте команды для умножения  (MUL):  а)  слова  DATAX  на
слово DATAY;  б) двойного слова ,  начинающегося по адресу DATAX, на слово
DATAY.

     12.4. Какой делитель, кроме нуля, вызывает ошибку переполнения?

     12.5. Закодируйте команды для деления (DIV): а) слова DATAX на 23; б)
двойного слова, начинающегося по адресу DATAX, на слово DATAY.

     12.6. Последний пример  в  разделе  "Сдвиг  регистровой  пары  DX:AX"
является более эффективным по сравнению с предыдущими примерами для сдвига
влево на четыре бита. Измените пример для сдвига вправо на четыре бита.



ГЛАВА 13                           Арифметические операции II:
                                   Обработка данных в форматах ASCII и BCD
__________________________________________________________________________

     Ц е л ь: Рассмотреть ASCII и BCD форматы данных  и  дать  сведения  о
преобразованиях между этими форматами и двоичным форматом.


     ВВЕДЕНИЕ
     ________________________________________________________________

     Для  получения  высокой  производительности    компьютер    выполняет
aрифметические операции над числами в двоичном  формате.  Как  показано  в
гл.12, этот формат не вызывает особых трудностей, если данные определены в
самой  программе.  Во  многих  случаях  новые данные вводятся программой с
клавиатуры в виде ASCII символов в деcятичном  формате.  Аналогично  вывод
информации  на  экран осуществляется в кодах ASCII.  Например,  число 23 в
двоичном представлении выглядит как 00010111 или шест.17;  в коде ASCII на
каждый cимвол требуется один байт и число 25 в ASCII-коде имеет внутpеннее
представление шест.3235.
     Назначение данной главы - показать технику преобразования  данных  из
ASCII-формата в двоичный формат для выполнения арифметических  операций  и
обратного преобразования двоичных результатов в ASCII-формат для вывода на
экран или принтер.  Программа, приведенная в конце главы  ,  демонстрирует
большую часть матеpиала гл.1 - 12.
     При программировании на языках высокого уровня, таких как  BASIC  или
Pascal, для обозначения порядка числа  или  положения  десятичной  запятой
(точки) можно положиться на компилятор.  Однако, компьютер  не  распознает
десятичную запятую (точку) в арифметических полях.  Так как двоичные числа
не имеют возможности установки десятичной (или двоичной) запятой  (точки),
то  именно  программист  должен  подразумевать  и    определить    порядок
обрабатываемых чисел.


     ASCII-ФОРМАТ
     ________________________________________________________________

     Данные, вводимые с клавиатуры,  имеют ASCII-формат,  например,  буквы
SAM  имеют  в памяти шестнадцатиричное представление 53414D,  цифры 1234 -
шест.31323334.  Во многих случаях формат алфавитных данных,  например, имя
человека или описание статьи,  не меняется в программе.  Но для выполнения
арифметических   операций   над   числовыми   значениями,    такими    как
шест.31323334, требуется специальная обработка.
     С  помощью  следующих    ассемблерных    команд    можно    выполнять
арифметические операции непосредственно над числами в ASCII-формате:

AAA (ASCII Adjust for Addition - коррекция для сложения ASCII-кода)
AAD (ASCII Adjust for Division - коррекция для деления ASCII-кода)
AAM (ASCII Adjust for Multiplication - коррекция для умножения ASCII-кода)
AAS (ASCII Adjust for Subtraction - коррекция для вычитания ASCII-кода)

Эти команды кодируются без операндов и выполняют автоматическую  коррекцию
в регистре AX.  Коррекция необходима, так как ASCII-код  представляет  так
называемый распакованный десятичный формат,  в  то  время,  как  компьютер
выполняет арифметические операции в двоичном формате.


                         Сложение в ASCII-формате
                        --------------------------
     Рассмотрим процесс сложения чисел 8 и 4 в ASCII-формате:

                         Шест.     38
                                   34
                                   --
                         Шест.     6C

Полученная сумма  неправильна  ни  для  ASCII-формата,  ни  для  двоичного
формата.  Однако, игнорируя левую 6 и прибавив 6 к правой шест.C: шест.C +
6  =  шест.12  -  получим  правильный  результат  в  десятичном   формате.
Правильный пример слегка упрощен,  но  он  хорошо  демонстрирует  процесс,
который выполняет команда AAA при коррекции.
     В качестве примера, предположим, что регистр AX содержит шест.0038, а
регистр BX   -   шест.0034.  Числа  38  и  34  представляют  два  байта  в
ASCII-формате, которые необходимо сложить. Сложение и коррекция кодируется
следующими командами:

               ADD  AL,BL     ;Сложить 34 и 38
               AAA            ;Коррекция для сложения ASCII-кодов

Команда AAA проверяет правую шест. цифру (4 бита) в регистре AL.  Если эта
цифра находится между A и F  или  флаг  AF  равен  1,  то  к  регистру  AL
прибавляется  6,  а  к  регистру  AH  прибавляется  1,  флаги  AF  и    CF
устанавливаются в 1. Во всех случаях команда AAA устанавливает в  0  левую
шест. цифру в регистре AL. Результат - в регистре AX:

               После команды ADD:  006C
               После команды AAA:  0102

     Для  того,  чтобы  выработать   окончательное    ASCII-представление,
достаточно просто поставить тройки на место левых шест. цифр:

               OR   AX,3030H  ;Результат 3132

     Все  показанное  выше  представляет  сложение  однобайтовых    чисел.
Сложение многобайтовых  ASCII-чисел  требует  организации  цикла,  который
выполняет обработку справа налево с учетом переноса.  Пример ,  показанный
на рис.13.1 складывает  два  трехбайтовых  ASCII-числа  в  четырехбайтовую
сумму. Обратите внимание на следующее:

__________________________________________________________________________

TITLE   ASCADD  (COM) Сложение чисел в ASCII-формате
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG
        ORG     100H
BEGIN:  JMP     SHORT MAIN
; -----------------------------------------------
ASC1    DB      '578'        ;Элементы данных
ASC2    DB      '694'
ASC3    DB      '0000'
; -----------------------------------------------
MAIN    PROC    NEAR
        CLC
        LEA     SI,AASC1+2   ;Адреса ASCII-чисел
        LEA     DI,AASC2+2
        LEA     BX,AASC1+3
        MOV     CX,03        ;Выполнить 3 цикла
A20:
        MOV     AH,00        ;Очистить регистр AH
        MOV     AL,[SI]      ;Загрузить ASCII-байт
        ADC     AL,[DI]      ;Сложение (с переносом)
        AAA                  ;Коррекция для ASCII
        MOV     [BX],AL      ;Сохранение суммы
        DEC     SI
        DEC     DI
        DEC     BX
        LOOP    A20          ;Циклиться 3 раза
        MOV     [BX],AH      ;Сохранить перенос
        RET
MAIN    ENDP
CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.13.1. Сложение в ASCII-формате.


          - В программе используется команда ADC,  так как любое  сложение
     может  вызвать  перенос,  который  должен быть прибавлен к следующему
     (слева) байту. Команда CLC устанавливает флаг CF в нулевое состояние.
          - Команда MOV очищает регистр AH в каждом цикле, так как команда
     AAA может прибавить к нему единицу.  Команда ADC учитывает  пеpеносы.
     Заметьте,  что  использование команд XOR или SUB для oчистки регистра
     AH изменяет флаг CF.
          - Когда    завершается   каждый   цикл,   происходит   пересылка
     содержимого pегистра AH (00 или 01) в левый байт суммы.
          - В  результате  получается сумма в виде 01020702.  Программа не
     использует команду OR после команды AAA для занесения  левой  тройки,
     так как  при  этом  устанавливается  флаг  CF,  что изменит pезультат
     команды ADC.  Одним из решений в данном  случае  является  сохранение
     флагового регистра с помощью команды PUSHF, выполнение команды OR, и,
     затем, восстановление флагового регистра командой POPF:

               ADC  AL,[DI]   ;Сложение с переносом
               AAA            ;Коррекция для ASCII
               PUSHF          ;Сохранение флагов
               OR   AL,30H    ;Запись левой тройки
               POPF           ;Восстановление флагов
               MOV  [BX],AL   ;Сохранение суммы

     Вместо команд PUSHF и POPF можно использовать команды LAHF  (Load  AH
with Flags - загрузка флагов в регистр  AH)  и  SAHF  (Store  AH  in  Flag
register - запись флагов из регистра AH во флаговый регистр). Команда LAHF
загружает в регистр AH  флаги  SF,  ZF,  AF,  PF  и  CF;  а  команда  SAHF
записывает  содержимое  регистра  AH  в  указанные  флаги.  В  приведенном
примере,  однако,  регистр  AH  уже  используется    для    арифметических
переполнений. Другой способ вставки троек для получения ASCII-кодов цифр -
организовать обработку суммы командой OR в цикле.


                        Вычитание в ASCII-формате
                       ---------------------------
     Команда AAS (ASCII Adjust for Subtraction - коррекция  для  вычитания
ASCII-кодов) выполняется aналогично команде  AAA.  Команда  AAS  проверяет
правую шест. цифру (четыре бита) в регистре AL. Если эта цифра лежит между
A и F или флаг AF равен 1,  то из регистра AL вычитается 6,  а из регистра
AH  вычитается  1,  флаги  AF  и  CF устанавливаются в 1.  Во всех случаях
команда AAS устанавливает в 0 левую шест.цифру в регистpе AL.
     В следующих двух примерах  предполагается,  что  поле  ASC1  содержит
шест.38, а поле ASC2 - шест.34:

               Пример 1:                  AX      AF

                    MOV  AL,ASC1        ;0038
                    SUB  AL,ASC2        ;0034     0
                    AAS                 ;0004     0


               Пример 2:                  AX      AF

                    MOV  AL,ASC2        ;0034
                    SUB  AL,ASC1        ;00FC     1
                    AAS                 ;FF06     1

В примере 1 команде AAS не требуется выполнять коррекцию. В примере 2, так
как правая цифра в регистре AL равна шест.C, команда  AAS  вычитает  6  из
регистра AL и 1 из регистра  AH  и  устанавливает  в  1  флаги  AF  и  CF.
Результат (который должен быть равен -4) имеет шест.  представление  FF06,
т.е. десятичное дополнение числа -4.


                        Умножение в ASCII-формате
                       ---------------------------
     Команда  AAM  (ASCII  Adjust  for  Multiplication  -  коррекция   для
умножения ASCII-кодов)  выполняет   корректировку   результата   умножения
ASCII-кодов  в  регистре AX.  Однако,  шест.  цифры должны быть очищены от
троек  и  полученные  данные  уже  не   будут   являться   действительными
ASCII-кодами.  (В  руководствах  фирмы  IBM  для таких данных используется
термин pаспакованный десятичный формат).  Например,  число в ASCII-формате
31323334  имеет  распакованное  десятичное  представление 01020304.  Кроме
этого,  надо помнить, что коррекция осуществляется только для одного байта
за одно выполнение,  поэтому можно умножать только oдно-байтовые поля; для
более длинных полей необходима организация цикла.
     Команда AAM делит содержимое регистра AL на 10 (шест.0A) и записывает
частное в регистр AH,  а остаток в AL.  Предположим,  что  в  регистре  AL
содержится шест.35,  а в регистре CL - шест.39. Следующие команды умножают
содержимое  регистра  AL  на  содержимое  CL  и  преобразуют  результат  в
ASCII-формат:

                                                            AX:
               AND  CL,0FH    ;Преобразовать CL в 09
Предыдущая страница Следующая страница
1 ... 30 31 32 33 34 35 36  37 38 39 40 41 42 43 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама