4.5. Арифметический пример

Чтобы проиллюстрировать функции, которые мы рассмотрели в предыдущих разделах, давайте решим арифиетическую задачу на языке ассемблера. Пример прост, но использует многие команды. Задача заключается в вычислении частного двух арифметических выражений, в которых некоторые числа постоянны, а другие переменны. Все числа являются 16-битовыми целыми числами со знаком. Формула вычислений:


      A * 2 + B * C
X = -----------------
          D - 3

Эта задача решается подпрограммой на языке ассемблера, изображенной на Фиг. 4.16. Подпрограмма сначала выполняет два умножения. Так как микропроцессор 8088 всегда помещает результат 16-битового умножения в пару регистров DX:AX, в примере результат первого умножения переносится в пару регистров BX:CX перед выполнением второго умножения. Когда оба умножения завершены, программа выполняет сложение числителя. Поскольку умножение дает 32-битовые результаты, в программе требуется сложение повышенной точности. Это сложение оставляет результат в DX:AX. В примере знаменатель вычисляется в регистре CX, а затем на него делится числитель. Программа записывает частное из регистра AX в переменную результата X. Остаток в этой задаче игнорируется.


Microsoft (R) Macro Assembler Version 5.00                  1/1/80 04:01:10
Фиг. 4.16 Пример арифметических вычислений                        Page  1-1
                         PAGE     ,132
                         TITLE    Фиг. 4.16 Пример арифметических вычислений
                         ;-------------------------------------------------------------
                         ; Производятся вычисления по формуле
                         ;
                         ;                  A * 2 + B * C
                         ;            X = -----------------
                         ;                      D - 3
                         ;
                         ; Все переменные - 16-разрядные целые числа со знаком
                         ;-------------------------------------------------------------

                                Фиг. 4.16 Арифметический пример (начало)

0000                     CODE     SEGMENT
                         ASSUME   CS:CODE,DS:CODE
0000    ????             X        DW        ?           ; Память для переменных
0002    ????             A        DW        ?
0004    ????             B        DW        ?
0006    ????             C        DW        ?
0008    ????             D        DW        ?
000A                     FIG4_16  PROC      NEAR
000A    B8 0002                   MOV       AX, 2       ; Загрузка константы
000D    F7 2E 0002 R              IMUL      A           ; DX:AX = A * 2
0011    8B DA                     MOV       BX, DX
0013    8B C8                     MOV       CX, AX      ; BX:CX = A * 2
0015    A1 0004 R                 MOV       AX, B
0018    F7 2E 0006 R              IMUL      C           ; DX:AX = B * C
001C    03 C1                     ADD       AX, CX
001E    13 D3                     ADC       DX, BX      ; DX:AX = A * 2    +    B * C
0020    8B 0E 0008 R              MOV       CX, D
0024    83 E9 03                  SUB       CX, 3       ; CX = D - 3
0027    F7 F9                     IDIV      CX          ; AX = (A*2 + B*C) / (D-3)
0029    A3 0000 R                 MOV       X, AX       ; Сохранение результата
002C    C3                        RET
002D                       FIG4_16 ENDP
002D                       CODE   ENDS
                           END

                               Фиг. 4.16 Арифметический пример (продолжение)