Главная · Поиск книг · Поступления книг · 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 ... 31 32 33 34 35 36 37  38 39 40 41 42 43 44 ... 85
               AND  AL,0FH    ;Преобразовать AL в 05        0005
               MUL  CL        ;Умножить AL на CL            002D
               AAM            ;Преобразовать в распак.дес.  0405
               OR   AX,3030H  ;Преобразовать в ASCII-ф-т    3435

Команда MUL генерирует 45 (шест.002D) в регистре AX,  после  чего  команда
AAM делит это значение на 10, записывая частное 04 в регистр AH и  остаток
05 в регистр AL.  Команда OR преобpазует  затем  распакованное  десятичное
число в ASCII-формат.
     Пример на рис.13.2 демонстрирует умножение четырехбайтового множимого
на однобайтовый  множитель.  Так как команда AAM может иметь дело только с
однобайтовыми  числами,  то  в   программе   организован   цикл,   который
обрабатывает  байты  справа  налево.  Окончательный  результат умножения в
данном примере - 0108090105.
     Если множитель больше одного байта, то необходимо обеспечить еще один
цикл,  который  обрабатывает  множитель.  В  этом  случае   проще    будет
преобразовать число из ASCII-формата  в  двоичный  формат  (см.  следующий
раздел "Преобразование ASCII-формата в двоичный формат").

__________________________________________________________________________

TITLE   ASCMUL  (COM) Умножение ASCII-чисел
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG
        ORG     100H
BEGIN:  JMP     MAIN
; ---------------------------------------------
MULTCND DB      '3783'          ;Элементы данных
MULTPLR DB      '5'
PRODUCT DB      5 DUP(0)
; ---------------------------------------------
MAIN    PROC    NEAR
        MOV     CX,04           ;4 цикла
        LEA     SI,MULTCND+3
        LEA     DI,PRODUCT+4
        AND     MULTPLR,0FH     ;Удалить ASCII-тройку
A20:
        MOV     AL,[SI]         ;Загрузить ASCII-символ
                                ; (можно LODSB)
        AND     AL,OFH          ;Удалить ASCII-тройку
        MUL     MULTPLR         ;Умножить
        AAM                     ;Коррекция для ASCII
        ADD     AL,[DI]         ;Сложить с
        AAA                     ; записанным
        MOV     [DI],AL         ; произведением
        DEC     DI
        MOV     [DI],AH         ;Записать перенос
        DEC     SI
        LOOP    A20             ;Циклиться 4 раза
        RET
MAIN    ENDP
CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.13.2. Умножение в ASCII-формате.


                         Деление в ASCII-формате
                        -------------------------
     Команда AAD  (ASCII  Adjust  for  Division  -  коррекция  для деления
ASCII-кодов)    выполняет    корректировку    ASCII-кода    делимого    до
непосредственного деления. Однако, прежде необходимо очистить левые тройки
ASCII-кодов для получения распакованного десятичного формата.  Команда AAD
может оперировать с двухбайтовыми делимыми в регистре AX. Предположим, что
регистр AX содержит делимое 3238 в ASCII-формате  и  регистр  CL  содержит
делитель  37 также в ASCII-формате.  Следующие команды выполняют коррекцию
для последующего деления:
                                                            AX:
          AND  CL,0FH    ;Преобразовать CL в распак.дес.
          AND  AX,0F0FH  ;Преобразовать AX в распак.дес.    0208
          AAD            ;Преобразовать в двоичный          001C
          DIV  CL        ;Разделить на 7                    0004

Команда AAD умножает содержимое AH на 10 (шест.0A),  прибавляет  pезультат
20 (шест.14) к регистру AL и очищает регистр AH.  Значение 001C есть шест.
представление  десятичного  числа  28.  Делитель   может    быть    только
однобайтовый от 01 до 09.
     Пример на  рис.13.3  выполняет  деление  четырехбайтового делимого на
однобайтовый делитель.  В программе организован  цикл  обработки  делимого
справа  налево.  Остатки  от деления находятся в регистре AH и команда AAD
корректирует их в регистре AL. Окончательный pезультат: частное 00090204 и
в регистре AH остаток 02.
     Если делитель больше одного байта,  то  необходимо  построить  другой
цикл для обработки делителя, но лучше воспользоваться  следующим  разделом
"Преобразование ASCII-формата в двоичный формат."

__________________________________________________________________________

TITLE   ASCDIV  (COM) Деление ASCII-чисел
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG
        ORG     100H
BEGIN:  JMP     SHORT MAIN
; ---------------------------------------------
DIVDND  DB      '3698'          ;Элементы данных
DIVSOR  DB      '4'
QUOTNT  DB      4 DUP(0)
; ---------------------------------------------
MAIN    PROC    NEAR
        MOV     CX,04           ;4 цикла
        SUB     AH,AH           ;Стереть левый байт делимого
        AND     DIVSOR,0FH      ;Стереть ASCII 3 в делителе
        LEA     SI,DIVDND
        LEA     DI,QUOTNT
A20:
        MOV     AL,[SI]         ;Загрузить ASCII байт
                                ; (можно LODSB)
        AND     AL,0FH          ;Стереть ASCII тройку
        AAD                     ;Коррекция для деления
        DIV     DIVSOR          ;Деление
        MOV     [DI],AL         ;Сохранить частное
        INC     SI
        INC     DI
        LOOP    A20             ;Циклиться 4 раза
        RET
MAIN    ENDP
CODEGS  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.13.3. Деление в ASCII-формате.


     ДВОИЧНО-ДЕСЯТИЧНЫЙ ФОРМАТ (BCD)
     ________________________________________________________________

     В предыдущем примере деления в ASCII-формате  было  получено  частное
00090204. Если сжать это значение, сохраняя только  правые  цифры  каждого
байта, то получим 0924. Такой формат называется двоично-десятичным (BCD  -
Binary Coded Decimal) (или упакованным).  Он  содержит  только  десятичные
цифры от 0 до 9. Длина двоично-десятичного представления в два раза меньше
ASCII-представления.
     Заметим, однако, что десятичное число  0924  имеет  основание  10  и,
будучи преобразованным в основание 16 (т.е. в шест.  представление),  даст
шест.039C.
     Можно выполнять  сложение  и  вычитание  чисел  в  двоично-десятичном
представлении (BCD-формате).  Для этих целей  имеются  две  корректиpующих
команды:

DAA  (Decimal Adjustment for Addition - десятичная коррекция для сложения)
DAS  (Decimal Adjustment for Subtraction - десятичн. коррекция для вычит.)

     Обработка  полей  также  осуществляется  по  одному  байту  за   одно
выполнение. В примере  программы,  приведенном  на  рис.13.4,  выполняется
преобразование   чисел  из  ASCII-формата  в  BCD-формат  и  сложение  их.
Процедура  B10CONV  преобразует  ASCII  в  BCD.  Обработка   чисел   может
выполняться как справа налево,  так и слева направо. Кроме того, обработка
слов проще,  чем обработка байтов,  так как  для  генерации  одного  байта
BCD-кода  требуется  два  байта  ASCII-кода.  Ориентация на обработку слов
требует четного количества байтов в ASCII-поле.
     Процедура  C10ADD  выполняет   сложение    чисел    в    BCD-формате.
Окончательный результат - 127263.

__________________________________________________________________________

TITLE BCDADD (СОМ) Преобр.ASCII в BCD, сложение
CODESG  SEGMENT PARA "Code"
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG
        ORG     100H
BEGIN:  JMP     SHORT MAIN
; -------------------------------------------
ASC1    DB      '057836'
ASC2    DB      '069427'
BCD1    DB      '000'
BCD2    DB      '000'
BCD3    DB      4 DUP(0)
; -------------------------------------------
MAIN    PROC    NEAR
        LEA     SI,ASC1+4          ;Инициализировать для ASC1
        LEA     DI,BCD1+2
        CALL    B10CONV            ;Вызвать преобразование
        LEA     SI,ASC2+4          ;Инициализировать для ASC2
        LEA     DI,BCD2+2
        CALL    B10CONV            ;Вызвать преобразование
        CALL    C10ADD             ;Вызвать сложение
        RET
MAIN    ENDP
;               Преобразование ASCII в BCD:
;               --------------------------
B10CONV PROC
        MOV     CL,04              ;Фактор сдвига
        MOV     OX,03              ;Число слов В20:
        MOV     AX,[SI]            ;Получить ASCII-пapy
                                   (можно использовать LODSW)
        XCHG    AH,AL
        SHL     AL,CL              ;Удалить тройки
        SHL     AX,CL              ; ASCII-кода
        MOV     [DI],AH            ;Записать BCD-цифру
        DEC     SI
        DEC     SI
        DEC     DI
        DEC     DX
        JNZ     В20
        RET
B10CONV ENDP
;               Сложение BCD-чисел:
;               ------------------
C10ADD PROC
       XOR      AН,AН              ;0чистить AН
       LEA      SI,BCD1+2          ;Инициализация
       LEA      DI,BCD2+2          ; BCD
       LEA      BX,BCD3+3          ; адресов
       MOV      CX,03              ;Трехбайтные поля
       CLC
С20:
       MOV      AL,[SI]            ;Получить BCD1 (или LODSB)
       ADC      AL,[DI]            ;Прибавить BCD2
       DAA                         ;Десятичная коррекция
       MOV      [BX],AL            ;3аписать в BCD3
       DEC      SI
       DEC      DI
       DEC      BX
       LOOP     С20                ;Цикл 3 раза
       RET
C10ADD ENDP

CODESG ENDS
       END      BEGIN
__________________________________________________________________________

     Рис.13.4. BCD-преобразование и арифметика.


     ПРЕОБРАЗОВАНИЕ ASCII-ФОРМАТА В ДВОИЧНЫЙ ФОРМАТ
     ________________________________________________________________

     Выполнение арифметических  операций  над  числами  в  ASCII  или  BCD
форматах удобно  лишь  для  коротких  полей.  В  большинстве  случаев  для
арифметических операций используется  преобразование  в  двоичный  формат.
Практически  проще  преобразование  из  ASCII-формата  непосредственно   в
двоичный формат, чем преобразование из ASCII- в  BCD-формат  и,  затем,  в
двоичный формат:
     Метод  преобразования  базируется  на  том,  что  ASCII-формат  имеет
основание 10, а компьютер выполняет  арифметические  операции  только  над
числами с основанием 2. Процедура преобразования заключается в следующем:

          1. Начинают с самого  правого  байта  числа  в  ASCII-формате  и
     обрабатывают справа налево.
          2. Удаляют тройки из левых шест.цифр каждого ASCII-байта.
          3. Умножают ASCII-цифры на 1, 10, 100 (шест.1, A, 64) и  т.д.  и
     складывают результаты.

     Для примера рассмотрим преобразование числа 1234 из  ASCII-формата  в
двоичный формат:

                              Десятичное     Шестнадцатиричное

               4 х 1 =                4              4
               3 х 10 =              30             1E
               2 х 100 =            200             C8
               1 х 1000 =          1000            3E8
               Результат:                         04D2

     Проверьте,  что  шест.04D2  действительно  соответствует  десятичному
1234. На   рис.13.5   в   процедуре   B10ASBI  выполняется  преобразование
ASCII-числа 1234 в двоичный формат.  В примере предполагается,  что  длина
ASCII-числа равна 4 и она записана в поле ASCLEN.  Для инициализации адрес
ASCII-поля ASCVAL-1 заносится в регистр  SI,  а  длина  -  в  регистр  BX.
Команда по метке B20 пересылает ASCII-байт в регистр AL:

               MOV  AL,[SI+BX]

     Здесь используется адрес ASCVAL-1 плюс содержимое  регистра  BX  (4),
т.е. получается адрес ASCVAL+3 (самый правый байт поля ASCVAL).  В  каждом
цикле содержимое регистра BX уменьшается на 1, что приводит к обращению  к
следующему слева байту.  Для данной адресации можно  использовать  регистр
BX, но не CX, и, следовательно, нельзя применять команду  LOOP.  В  каждом
цикле происходит также умножение поля MULT10 на 10, что дает в  результате
Предыдущая страница Следующая страница
1 ... 31 32 33 34 35 36 37  38 39 40 41 42 43 44 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама