Главная · Поиск книг · Поступления книг · 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 ... 29 30 31 32 33 34 35  36 37 38 39 40 41 42 ... 85
     В четвертом примере команды DIV сначала выполняется расширение  слова
WORD1 до двойного слова в регистре DX.  После  деления  остаток  шест.0000
получится в регистре DX, а частное шест.0002 - в регистре AX.

__________________________________________________________________________

        page    60,132
TITLE   EXDIV   (COM) Пример операций DIV и IDIV
CODESG  SEGMENT PARA 'Code'
        ORG     100H
BEGIN:  JMP     SHORT MAIN
; ---------------------------------------------
BYTE1   DB      80H           ;Data items
BYTE2   DB      16H
WORD1   DW      2000H
WORD2   DW      0010H
WORD3   DW      1000H
; ---------------------------------------------
MAIN    PROC    NEAR          ;Основная процедура
        CALL    D10DIV        ;Вызов подпрограммы DIV
        CALL    E10IDIV       ;Вызов подпрограммы IDIV
MAIN    ENDP
;               Примеры с командой DIV:
; ---------------------------------------------
D10DIV  PROC
        MOV     AX,WORD1      ;Слово / байт
        DIV     BYTE1         ; остаток:частное в AH:AL
        MOV     AL,BYTE1      ;Байт / байт
        SUB     AH,AH         ; расширить делимое в AH
        DIV     BYTE3         ; остаток:частное в AH:AL

        MOV     DX,WORD2      ;Двойное слово / слово
        MOV     AX,WORD3      ; делимое в DX:AX
        DIV     WORD1         ; остаток:частное в DX:AX
        MOV     AX,WORD1      ;Слово / слово
        SUB     DX,DX         ; расширить делимое в DX
        DIV     WORD3         ; остаток:частное в DX:AX
        RET
D10DIV  ENDP
;               Примеры с командой IDIV:
; ---------------------------------------------
E10IDIV PROC
        MOV     AX,WORD1      ;Слово / байт
        IDIV    BYTE1         ; остаток:частное в AH:AL
        MOV     AL,BYTE1      ;Байт / байт
        CBW                   ; расширить делимое в AH
        IDIV    BYTE3         ; остаток:частное в AH:AL

        MOV     DX,WORD2      ;Двойное слово / слово
        MOV     AX,WORD3      ; делимое в DX:AX
        IDIV    WORD1         ; остаток:частное в DX:AX
        MOV     AX,WORD1      ;Слово / слово
        CWD                   ; расширить делимое в DX
        IDIV    WORD3         ; остаток:частное в DX:AX
        RET
E10DIV  ENDP
CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.12.5. Беззнаковое и знаковое деление.


                      Знаковое деление: Команда IDIV
                     --------------------------------
     Команда IDIV (Integer DIVide) выполняет деление  знаковых  чисел.  На
рис.12.5 в процедуре E10IDIV используются те же  четыре  примера  деления,
что и в процедуре D10DIV, но вместо  команд  DIV  записаны  команды  IDIV.
Первый пример  команды  IDIV  делит  шест.2000  (положительное  число)  на
шест.80 (отрицательное число).  Остаток от деления - шест. 00 получается в
регистре AH , а частное - шест.  C0 (-64) - в регистре  AL.  Команда  DIV,
используя те же числа, генерирует частное +64.
     Шестнадцатиричные  результаты  трех  остальных    примеров    деления
приведены ниже:

          Пример команды IDIV        Остаток        Частное

                      2              EE (-18)       FB (-5)
                      3            1000 (4096)    0080 (128)
                      4            0000           0002

Только в примере 4 вырабатывается такой же результат, что  и  для  команды
DIV. Таким образом, если делимое и делитель имеют одинаковый знаковый бит,
то команды DIV и IDIV генерируют одинаковый pезультат.  Но, если делимое и
делитель  имеют  разные  знаковые  биты,  то  команда    DIV    генерирует
положительное частное, а  команда  IDIV  -  отрицательное  частное.  Можно
обнаружить это, используя отладчик DEBUG для трассировки этих примеров.
     Повышение производительности. При делении на степень числа 2 (2, 4, и
т.д.) более эффективным является сдвиг вправо на требуемое число битов.  В
следующих примерах предположим, что делимое находится в регистре AX:

               Деление на 2:       SHR  AX,1

               Деление на 8:       MOV  CL,3
                                   SHR  AX,CL


                        Переполнения и прерывания
                       ---------------------------
     Используя  команды  DIV  и  особенно  IDIV,  очень  просто    вызвать
пеpеполнение. Прерывания приводят (по крайней мара в системе, используемой
при тестировании этих программ) к непредсказуемым результатам. В операциях
деления предполагается,  что  частное  значительно  меньше,  чем  делимое.
Деление на ноль всегда вызывает прерывание.  Но деление  на  1  генерирует
частное, которое равно делимому, что может также легко вызвать прерывание.
     Рекомендуется использовать следующее правило: если делитель  -  байт,
то его значение должно быть меньше, чем левый  байт  (AH)  делителя:  если
делитель - слово, то его значение должно быть меньше, чем левое слово (DX)
делителя. Проиллюстрируем данное правило для делителя, равного 1:

          Операция деления:          Делимое   Делитель  Частное

          Слово на байт:                0123        01     (1)23
          Двойное слово на слово:  0001 4026      0001   (1)4026

В обоих  случаях  частное  превышает  возможный  размер.  Для  того  чтобы
избежать подобных ситуаций, полезно вставлять перед командами DIV  и  IDIV
соответствующую проверку.  В первом из следующих примеpов предположим, что
DIVBYTE - однобайтовый делитель, а делимое находится уже в регистре AX. Во
втором примере предположим, что DIVWORD - двухбайтовый делитель, а делимое
находится в регистровой паре DX:AX.

               Слово на байт            Двойное слово на байт

               CMP  AH,DIVBYTE          CMP  DX,DIVWORD
               JNB  переполнение        JNB  переполнение
               DIV  DIVBYTE             DIV  DIVWORD

     Для команды IDIV данная логика должна учитывать тот  факт,  что  либо
делимое, либо делитель могут быть отрицательными, а так  как  сравниваются
абсолютные значения, то необходимо использовать команду NEG для временного
перевода отрицательного значения в положительное.


                            Деление вычитанием
                           --------------------
     Если частное слишком велико, то деление  можно  выполнить  с  помощью
циклического вычитания.  Метод заключается в том, что делитель  вычитается
из делимого и в этом  же  цикле  частное  увеличивается  на  1.  Вычитание
продолжается, пока делимое остается больше делителя.  В cледующем примере,
делитель находится в регистре AX, а делимое - в BX, частное вырабатывается
в CX:

                    SUB  CX,CX     ;Очистка частного
               C20: CMP  AX,BX     ;Если делимое < делителя,
                    JB   C30       ; то выйти
                    SUB  AX,BX     ;Вычитание делителя из делимого
                    INC  CX        ;Инкремент частного
                    JMP  C20       ;Повторить цикл
               С30: RET            ;Частное в CX, остаток в AX

     В конце подпрограммы регистр CX  будет  содержать  частное,  а  AX  -
oстаток.  Пример умышленно  примитивен  для  демонстрации  данной  техники
деления.  Если частное получается в регистровой паре DX:AX, то  необходимо
сделать два дополнения:

          1. В метке C20 сравнивать AX и BX  только при нулевом DX.
          2. После команды SUB вставить команду SBB DX,00.

     П р и м е ч а н и е: очень большое частное  и  малый  делитель  могут
вызвать тысячи циклов.


     ПРЕОБРАЗОВАНИЕ ЗНАКА
     ________________________________________________________________

     Команда NEG  обеспечивает  преобразование  знака  двоичных  чисел  из
положительного  в  отрицательное  и  наоборот.  Практически  команда   NEG
устанавливает противоположные значения битов и прибавляет 1. Примеры:

               NEG  AX
               NEG  BL
               NEG  BINAMT    ;(байт или слово в памяти)

     Преобразование знака для 35-битового (или  большего)  числа  включает
больше шагов.  Предположим, что регистровая пара DX:AX содержит 32-битовое
двоичное число.  Так как команда NEG не может  обрабатывать  два  регистра
одновременно, то ее использование приведет к неправильному  результату.  В
следующем примере показано использование команды NOT:

               NOT  DX   ;Инвертирование битов
               NOT  AX   ;Инвертирование битов
               ADD  AX,1 ;Прибавление 1 к AX
               ADC  DX,0 ;Прибавление переноса к DX

     Остается одна незначительная проблема: над числами, представленными в
двоичном формате, удобно  выполнять  арифметические  операции,  если  сами
числа определены в программе.  Данные, вводимые в  программу  с  дискового
файла,  могут  также  иметь  двоичный  формат.  Но  данные,  вводимые    с
клавиатуры, представлены  в  ASCII-формате.  Хотя  ASCII-коды  удобны  для
отображения и печати,  они требуют специальных преобразований  в  двоичный
формат для арифметических вычислений. Но это уже тема следующей главы.


     ПРОЦЕССОРЫ INTEL 8087 И 80287 ДЛЯ ОБРАБОТКИ ЧИСЛОВЫХ ДАННЫХ
     ________________________________________________________________

     Системная плата компьютера содержит пустое гнездо,  зарезервированное
для  числового  процессора  Intel  8087  (или  80287).  Сопроцессор   8087
действует совместно с 8088, а  сопроцессор  80287  действует  совместно  с
80286. Каждый сопроцессор имеет собственный набор команд  и  средства  для
операций  с  плавающей   запятой    для    выполнения    экспоненциальных,
логарифмических и тригонометрических функций.  Сопроцессор содержит восемь
80-битовых  регистров  с  плавающей  запятой,  которые  могут  представить
числовые значения  до  10  в  400  степени.  Математические  вычисления  в
сопроцессоре выполняются примерно  в  100  раз  быстрее,  чем  в  основном
процессоре.
     Основной процессор выполняет специальные операции и передает числовые
данные  в  сопроцессор,  который  выполняет  необходимые   вычисления    и
возвращает результат.  Для ассемблирования  с  помощью  транслятора  MASM,
необходимо добавлять параметр /E или /R, например, MASM /R.


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

     - Будьте  особенно   внимательны   при   использовании   однобайтовых
pегистров. Знаковые значения здесь могут быть от -128 до +127.

     - Для  многословного  сложения  используйте  команду  ADC  для  учета
переносов от предыдущих сложений.  Если операция выполняется в  цикле,  то
используя команду CLC, установите флаг переноса в 0.

     - Используйте  команды  MUL  или DIV для беззнаковых данных и команды
IMUL или IDIV для знаковых.

     - При  делении  будьте  осторожны  с  переполнениями.  Если   нулевой
делитель  возможен,  то  обеспечьте  проверку  этой операции.  Кроме того,
делитель должен быть больше содержимого регистра AH  (для  байта)  или  DX
(для слова).

     - Для  умножения  или  деления  на  степень двойки используйте cдвиг.
Сдвиг вправо выполняется командой SHR для беззнаковых полей и командой SAR
для знаковых полей. Для сдвига влево используются идентичные команды SHL и
SAL.

     - Будьте внимательны при ассемблировании по умолчанию. Например, если
поле  FACTOR  определено  как  байт  (DB),  то команда MUL FACTOR полагает
множимое в регистре AL,  а команда DIV FACTOR полагает делимое в  регистре
AX.  Если FACTOR определен как слово (DW),  то команда MUL FACTOR полагает
множимое  в  регистре  AX,  а  команда  DIV  FACTOR  полагает  делимое   в
регистровой паре DX:AX.


     ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ
     ________________________________________________________________

     Все вопросы имеют отношение к следующим данным:

               DATAX     DW   0148H
                         DW   2316H
               DATAY     DW   0237H
                         DW   4052H
Предыдущая страница Следующая страница
1 ... 29 30 31 32 33 34 35  36 37 38 39 40 41 42 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама