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

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


    Прохождения игр    
Aliens Vs Predator |#9| Unidentified xenomorph
Aliens Vs Predator |#8| Tequila Rescue
Aliens Vs Predator |#7| Fighting vs Predator
Aliens Vs Predator |#6| We walk through the tunnels

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


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

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

Предыдущая страница Следующая страница
1 ... 27 28 29 30 31 32 33  34 35 36 37 38 39 40 ... 85
любой  длины.  Действие  начинается  со  сложения  самых    правых    слов
складываемых полей.  В первом цикле складываются правые cлова, во втором -
слова, расположенные левее.  При этом адреса  в  регистрах  SI,  DI  и  BX
уменьшаются на 2. По две команда DEC выполняют эту  операцию  для  каждого
регистра. Применять команду

               SUB  reg,02

в данном случае нельзя, т.к. при этом  будет  очищен  флаг  переноса,  что
приведет к искажению результата сложения.
     Ввиду наличия цикла, используется только одна команда  сложения  ADC.
Перед  циклом  команда  CLC  (CLear  Carry  -  очистить  флаг    переноса)
устанавливает нулевое значение флага переноса.  Для работы данного  метода
необходимо: 1) обеспечить смежность слов, 2)  выполнять  обработку  справа
налево и 3) загрузить в регистр CX число складываемых слов.
     Для многословного вычитания используется команда SBB  (SuBtract  with
Borrow  -  вычитание  с  заемом)  эквивалентная  команде  ADC.  Заменив  в
процедуре E10DWD (рис.12.2) команду ADC  на  SBB,  получим  процедуру  для
вычитания.


     БЕЗЗНАКОВЫЕ И ЗНАКОВЫЕ ДАННЫЕ
     ________________________________________________________________

     Многие числовые поля не имеют знака, например, номер абонента,  aдрес
памяти.  Некоторые  числовые  поля  предлагаются  всегда    положительные,
например, норма выплаты, день недели, значение числа ПИ.  Другие  числовые
поля являются знаковые, так как их содержимое может быть положительным или
отрицательным.  Например, долговой баланс покупателя, который  может  быть
отрицательным при переплатах, или алгебраическое число.
     Для беззнаковых величин все биты  являются  битами  данных  и  вместо
ограничения +32767 регистр может содержать числа до +65535.  Для  знаковых
величин левый байт является знаковым битом.  Команды ADD и SUB  не  делают
разницы между знаковыми и беззнаковыми величинами, они просто складывают и
вычитают биты.  В следующем примере сложения двух двоичных  чисел,  первое
число  содержит  единичный  левый  бит.  Для  беззнакового   числа    биты
представляют положительное число 249, для знакового - отрицательное  число
-7:

                              Беззнаковое    Знаковое
               11111001            249            -7
               00000010              2            +2
                                   ---            --
               11111011            251            -5

Двоичное представление результата сложения одинаково  для  беззнакового  и
знакового числа.  Однако, биты представляют +251 для беззнакового числа  и
-5  для  знакового.  Таким  образом,  числовое  содержимое   поля    может
интерпретироваться по разному.
     Состояние "перенос" возникает в том случае, когда имеется  пеpенос  в
знаковый разряд.  Состояние "переполнение" возникает в том  случае,  когда
перенос в знаковый разряд не  создает  переноса  из  разрядной  сетки  или
перенос из разрядной сетки происходит без переноса в знаковый разряд.  При
возникновении переноса   при   сложении   беззнаковых   чисел,   результат
получается неправильный:

                              Беззнаковое    Знаковое  CF   OF
               11111100            252            -4
               00000101              5            +5
                                   ---            --
               00000001              1             1    1    0
                              (неправильно)

     При возникновении переполнения при сложении знаковых чисел, результат
получается неправильный:

                              Беззнаковое    Знаковое  CF   OF
               01111001            121          +121
               00001011             11           +11
                                   ---          ----
               10000100            132          -124    0    1
                                          (неправильно)

     При операциях сложения и вычитания может  одновременно  возникнуть  и
переполнение, и перенос:

                              Беззнаковое    Знаковое  CF   OF
               11110110            246           -10
               10001001            137          -119
                                   ---          ----
               01111111            127          +127    1    1
                              (неправильно)  (неправильно)


     УМНОЖЕНИЕ
     ________________________________________________________________

     Операция умножения для беззнаковых данных выполняется командой MUL, а
для знаковых - IMUL (Integer  MULtiplication  -  умножение  целых  чисел).
Ответственность за контроль над форматом обрабатываемых чисел и  за  выбор
подходящей команды умножения лежит на самом программисте.  Существуют  две
основные операции умножения:

     "Б а й т   н а   б а й т".   Множимое  находится  в  регистре  AL,  а
множитель в байте памяти или  в  однобайтовом  регистре.  После  умножения
произведение находится в регистре AX.  Операция игнорирует и стиpает любые
данные, которые находились в регистре AH.

                       | AH |   AL   |            |    AX      |
         До умножения: |    |Множимое|     После: |Произведение|

     "С л о в о  н а  с л о в о".  Множимое находится  в  регистре  AX,  а
множитель - в слове памяти или в регистре.  После  умножения  произведение
находится в двойном слове, для которого требуется  два  регистра:  старшая
(левая) часть произведения находится в регистре  DX,  а  младшая  (правая)
часть в регистре AX.  Операция игнорирует и стирает любые данные,  которые
находились в регистре DX.

                       |   AX   |          |   DX   ||   AX   |
          До умножения:|Множимое|   После: |Ст.часть||Мл.часть|
                                           |   Произведение   |

     В единственном операнде команд  MUL  и  IMUL  указывается  множитель.
Рассмотрим следующую команду:

               MUL  MULTR

     Если поле MULTR определено как байт (DB),  то  операция  предполагает
умножение содержимого AL на значение байта из поля MULTR.  Если поле MULTR
определено как слово (DW), то операция предполагает умножение  содержимого
AX на значение слова из поля MULTR.  Если множитель находится в  регистре,
то длина регистра определяет тип операции, как это показано ниже:

          MUL  CL  ;Байт-множитель: множимое в AL, произвед. в AX
          MUL  BX  ;Слово-множитель:множимое в AX, произвед. в DX:AX


                    Беззнаковое умножение: Команда MUL
                   ------------------------------------
     Команда MUL (MULtiplication - умножение) умножает беззнаковые  числа.
На рис.12.3  в процедуре C10MUL дано три примера умножения:  байт на байт,
слово на слово и слово на байт. Первый пример команды MUL умножает шест.80
(128) на шест.47 (64). Произведение шест.2000 (8192) получается в регистре
AX.

__________________________________________________________________________

        page 60,132
TITLE   EXMULT  (COM) Пример команд умножения
CODESG  SEGMENT PARA 'Code'
        ASSUME  CS:CODESG,DS:CODESG,SS:CODESG
        OR6     100H
BEGIN:  JMP     SHORT MAIN
; -------------------------------------------
BYTE1   DB      80H
BYTE2   DB      40H
WORD1   DW      8000H
WORD2   DW      4000H
; -------------------------------------------
MAIN    PROC    NEAR               ;Основная процедура:
        CALL    C10MUL             ;Вызвать умнож. MUL
        CALL    D10IMUL            ;Вызвать умнож. IMUL
        RET
MAIN    ENDP
;               Пример умножения MUL:
;               --------------------
C10MUL  PROC
        MOV     AL,BYTE1           ;Байт * байт
        MUL     BYTE2              ; произведение в AХ
        MOV     AX,WORD1           ;Слово * слово
        MUL     WORD2              ; произведение в DX:AX
        MOV     AL,BYTE1           ;Байт * слово
        SUB     AН,AН              ; расшир. множ. в AН
        MUL     WORD1              ; произведение в DX:AX
        RET
C10MUL  ENDP
;               Пример умножения IMUL:
;               ---------------------
D10IMUL PROC
        MOV     AL,BYTE1           ;Байт * байт
        IMUL    BYTE2              ; произведение в AХ
        MOV     AX,WORD1           ;Слово * слово
        IMUL    WORD2              ; произвед. в DX:AX
        MOV     AL,BYTE1           ;Байт * слово
        CBW                        ; расшир. множ. в AН
        IMUL    WORD1              ; произвед. в DX:AX
        RET
D10IMUL ENDP

CODESG  ENDS
        END     BEGIN
__________________________________________________________________________

     Рис.12.3. Беззнаковое и знаковое умножение.


     Второй пример команды MUL генерирует шест.10000000 в регистpах DX:AX.
     Третий пример команды MUL выполняет умножение слова на байт и требует
расширение  байта  BYTE1  до  размеров  слова.  Так  как    предполагаются
беззнаковые величины, то в примере левый бит регистра AH равен нулю.  (При
использовании команды CBW значение левого бита регистpа AL  может  быть  0
или 1). Произведение - шест.00400000 получается в регистрах DX:AX.


                     Знаковое умножение: Команда IMUL
                    ----------------------------------
     Команда  IMUL  (Integer  MULtiplication  -  умножение  целых   чисел)
умножает знаковые числа.  На рис.12.3 в процедуре D10IMUL используются  те
же три примера умножения,  что и в процедуре C10MUL,  но вместо команд MUL
записаны команды IMUL.
     Первый пример команды IMUL умножает шест.80 (отрицательное число)  на
шест.40 (положительное  число).  Произведение  -  шест.E000  получается  в
регистре AX.  Используя те  же  данные,  команда  MUL  дает  в  результате
шест.2000, так что можно видеть разницу в использовании команд MUL и IMUL.
Команда MUL рассматривает шест.80 как +128, а команда IMUL - как  -128.  В
результате  умножения  -128  на  +64  получается  -8192  или    шест.E000.
(Попробуйте преобразовать шест.Е000 в десятичный формат).
     Второй  пример  команды  IMUL  умножает   шест.8000    (отрицательное
значение)  на  шест.2000  (положительное   значение).    Произведение    -
шест.F0000000  получается  в  регистрах  DX:AX  и    представляет    собой
oтрицательное значение.
     Третий пример команды  IMUL  перед  умножением  выполняет  расширение
байта  BYTE1  до  размеров  слова  в  регистре  AX.  Так   как    значения
предполагаются  знаковые,  то  в  примере  используется  команда  CBW  для
перевода левого знакового  бита  в  регистр  AH:  шест.80  в  pегистре  AL
превращается в шест.FF80 в регистре AX.  Поскольку множитель в слове WORD1
имеет также  отрицательное  значение,  то  произведение  должно  получится
положительное.  В самом деле: шест.00400000 в регистрах DX:AX -  такой  же
результат, как и в случае умножения  командой  MUL,  которая  предполагала
положительные сомножители.
     Таким образом, если множимое и множитель  имеет  одинаковый  знаковый
бит, то команды MUL и  IMUL  генерируют  одинаковый  результат.  Но,  если
сомножители имеют  разные  знаковые  биты,  то  команда  MUL  вырабатывает
положительный результат умножения, а команда IMUL - отрицательный.
     Можно  обнаружить  это,  используя  отладчик  DEBUG  для  трассировки
примеров.

     П о в ы ш е н и е  э ф ф е к т и в н о с т и  у м н о ж е н и я:  При
умножении на степень числа 2 (2,4,8 и  т.д.)  более  эффективным  является
сдвиг влево на требуемое  число  битов.  Сдвиг  более  чем  на  1  требует
загрузки величины сдвига в регистр CL.  В следующих примерах  предположим,
что множимое находится в регистре AL или AX:

               Умножение на 2:     SHL  AL,1
               Умножение на 8:     MOV  CL,3
                                   SHL  AX,CL


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

Реклама