Жанр: Учеба

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

сторінка №17

олнение команды 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-кодов) выполняется аналогично команде AAA. Команда AAS проверяет
правую шест. цифру (четыре бита) в регистре AL. Если эта цифра лежит между
A и F или флаг AF равен 1, то из регистра AL вычитается 6, а из регистра
AH вычитается 1, флаги AF и CF устанавливаются в 1. Во всех случаях
команда AAS устанавливает в 0 левую шест.цифру в регистре 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 для таких данных используется
термин распакованный десятичный формат). Например, число в ASCII-формате
31323334 имеет распакованное десятичное представление 01020304. Кроме
этого, надо помнить, что коррекция осуществляется только для одного байта
за одно выполнение, поэтому можно умножать только одно-байтовые поля; для
более длинных полей необходима организация цикла.
Команда AAM делит содержимое регистра AL на 10 (шест.0A) и записывает
частное в регистр AH, а остаток в AL. Предположим, что в регистре AL
содержится шест.35, а в регистре CL - шест.39. Следующие команды умножают
содержимое регистра AL на содержимое CL и преобразуют результат в
ASCII-формат:

AX:
AND CL,0FH ;Преобразовать CL в 09
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 преобразует затем распакованное десятичное
число в 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), прибавляет результат
20 (шест.14) к регистру AL и очищает регистр AH. Значение 001C есть шест.
представление десятичного числа 28. Делитель может быть только
однобайтовый от 01 до 09.
Пример на рис.13.3 выполняет деление четырехбайтового делимого на
однобайтовый делитель. В программе организован цикл обработки делимого
справа налево. Остатки от деления находятся в регистре AH и команда AAD
корректирует их в регистре AL. Окончательный результат: частное 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-формате). Для этих целей имеются две корректирующих
команды:

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-пару
(можно использовать 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 АН,АН ;0чистить АН
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,10,100 и т.д. Такой прием применен для большей ясности,
однако, для большей производительности множитель можно хранить в регистре
SI или DI.

__________________________________________________________________________

TITLE EXCONV (СОМ) Преобр. ASCII и дв. ф-тов
CODESG SEGMENT PARA 'Code'
ASSUME CS:CODESG,DS:CODESG,SS:CODESG
ORG 100H
BEGIN: JMP SHORT MAIN
; -------------------------------------------
ASCVAL DB '1234' ;Элементы данных
BINVAL DB 0
ASCLEN DB 4
MULT10 DB 1
; -------------------------------------------
MAIN PROC NEAR ;Основная процедура:
CALL B10ASBI ;Вызвать преобразование ASCII
CALL C10BIAS ;Вызвать преобразование двоичное
RET
MAIN ENDP
; -------------------------------
; Преобразование ASCII в двоичное:
; -------------------------------
B10ASBI PROC
МОV CX,10 ;Фактор умножения
LEA SI,ASCVAL-1 ;Адрес ASCVAL
MOV BX,ASCLEN ;Длина ASCVAL
В20:
MOV AL,[SI+BX] ;Выбрать ASCII-символ
AND AX,000FH ;Очистить зону тройки
MUL MULT10 ;Умножить на фактор 10
ADD BINVAL,AX ;Прибавить к двоичному
MOV AX,MULT10 ;Вычислить следующий
MUL CX ; фактор умножения
MOV MULT10,AX
DEC BX ;Последн. ASCII-символ?

JNZ В20 ; Нет - продолжить
RET
B10ASBI ENDP
; -------------------
; Преобр. дв. в ASCII:
; -------------------
C10BIAS PROC
MOV CX,0010 ;Фактор деления
LEA SI,ASCVAL+3 ;Адрес ASCVAL
MOV AX,BINVAL ;Загрузить дв. число
С20:
CMP АХ,0010 ;Значение меньше 10?
JB С30 ; Да - выйти
XOR DX,DX ;Очистить часть частного
DIV CX ;Разделить на 10
OR DL,30H
MOV [SI],DL ;Записать ASCII-символ
OEC SI
JMP С20
C30:
OR AL,30H ;3аписать посл. частное
MOV [SI],AL ; как ASCII-символ
RET
C10BIAS ENDP

CODESG ENDS
END BEGIN
__________________________________________________________________________

Рис.13.5. Преобразование ASCII и двоичного форматов.

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

Для того, чтобы напечатать или отобразить на экране арифметический
результат, необходимо преобразовать его в ASCII-формат. Данная операция
включает в себя процесс обратный предыдущему. Вместо умножения
используется деление двоичного числа на 10 (шест.0A) пока результат не
будет меньше 10. Остатки, которые лежат в границах от 0 до 9, образуют
число в ASCII-формате. В качестве примера рассмотрим преобразование
шест.4D2 обратно в десятичный формат:

Частное Остаток

4D2 : A 7B 4
7B : A C 3
C : A 1 2

Так как последнее частное 1 меньше, чем шест.A, то операция завершена.
Остатки вместе с последним частным образуют результат в ASCII-формате,
записываемый справа налево 1234. Все остатки и последнее частное должны
записываться в память с тройками, т.е. 31323334.
На рис.13.5 процедура C10BIAS преобразует шест.4D2 (результат
вычисления в процедуре B10ASBI) в ASCII-число 1234. Полезно переписать всю
программу (рис.13.5) в компьютер и выполнить трассировку ее выполнения по
шагам.

СДВИГ И ОКРУГЛЕНИЕ
________________________________________________________________

Рассмотрим процесс округления числа до двух десятичных знаков после
запятой. Если число равно 12,345, то необходимо прибавить 5 к
отбрасываемому разряду и сдвинуть число вправо на один десятичный разряд:

Число: 12,345
Плюс 5: +5
------
Округленное число: 12,350 = 12,35

Если округляемое число равно 12,3455, то необходимо прибавить 50 и
сдвинуть на два десятичных разряда. Для 12,34555 необходимо прибавить 500
и сдвинуть на три десятичных разряда:

12,3455 12,34555
+50 +500
------- --------
12,3505 = 12,35 12,35055 = 12,35

К числу, имеющему шесть знаков после запятой, необходимо прибавить 5000 и
сдвинуть на четыре десятичных разряда и т.д. Поскольку данные
представляются в компьютере в двоичном виде, то 12345 выглядит как
шест.3039. Прибавляя 5 к 3039, получим 303E, что соответствует числу 12350
в десятичном представлении. Пока все хорошо. Но вот сдвиг на одну двоичную
цифру дает в результате шест.181F, или 1675 - т.е. сдвиг на одну двоичную
цифру просто делит число пополам. Но нам необходим такой сдвиг, который
эквивалентен сдвигу вправо на одну десятичную цифру. Такой сдвиг можно
осуществить делением на 10 (шест.A):

Шест.303E : Шест.A = 4D3 или дес.1235

Преобразование шест.4D3 в ASCII-формат дает число 1235. Теперь остается
лишь вставить запятую в правильную позицию числа 12,35, и можно выдать на
экран округленное и сдвинутое значение.
Таким образом можно округлять и сдвигать любые двоичные числа. Для
трех знаков после запятой необходимо прибавить 5 и разделить на 10, для
четырех знаков после запятой: прибавить 50 и разделить на 100. Возможно вы
заметили модель: фактор округления (5, 50, 500 и т.д.) всегда составляет
половину фактора сдвига (10, 100, 1000 и т.д.).
Конечно, десятичная запятая в двоичном числе только подразумевается.

ПРОГРАММА: ПРЕОБРАЗОВАНИЕ ВРЕМЕНИ И РАСЦЕНКИ РАБОТ ДЛЯ РАСЧЕТА ЗАРПЛАТЫ
_______________________________________________________________________

Программа, приведенная на рис.13.6, позволяет вводить с клавиатуры
значения продолжительности и расценки работ и отображать на экран
расчитанную величину заработанной платы. Для краткости в программе опущены
некоторые проверки на ошибку. Программа содержит следующие процедуры:

B10INPT Вводит значения времени работы на ее расценку с клавиатуры. Эти
значения могут содержать десятичную запятую.
D10HOUR Выполняет преобразование значения времени из ASCII в двоичный
формат.
E10RATE Выполняет преобразование значения расценки из ASCII в двоичный
формат.
F10MULT Выполняет умножение, округление и сдвиг. Величина зарплаты без
дробной части или с одним или двумя знаками после запятой не
требует округления и сдвига. Данная процедура ограничена тем,
что позволяет обрабатывать величину зарплаты с точностью до
шести десятичных знаков, что, конечно, больше, чем требуется.
G10WAGE Вставляет десятичную запятую, определяет правую позицию для
начала записи ASCII символов и преобразует двоичное значение
зарплаты в ASCII-формат.
K10DISP Заменяет лидирующие нули на пробелы и выводит результат на экран
M10ASBI Преобразует ASCII в двоичный формат (общая процедура для времени
и расценки) и определяет число цифр после запятой в введенном
значении.

__________________________________________________________________________

TITLE SCREMP (EXE) Ввод времени и расценки,
;вывод величины оплаты
; ----------------------------------------------------
STACKSG SEGMENT PARA STACK 'Stack'
DW 32 DUP(?)
STACKSG ENDS
; ----------------------------------------------------
DATASG SEGMENT PARA 'Data'
HRSPAR LABLE BYTE ;Список параметров для
; ввода времени:
MAXHLEN DB 6 ;---------------------
ACTHLEN DB ?
HRSFLD DB 6 DUP(?)

RATEPAR LABLE BYTE ;Список параметров для
; ввода расценки:
MAXRLEN DB 6 ;---------------------
ACTRLEN DB ?
RATEFLN DB 6 DUP(?)

MESSG1 DB 'Hours worked? ','$'
MESSG2 DB 'Rate of pay? ','$'
MESSG3 DB 'Wage = '
ASCWAGE DB 10 DUP(30H), 13, 10, '$'
ADJUST DW ?

ASCHRS DB 0
ASCRATE DB 0
BINVAL DW 00
BINHRS DW 00
BINRATE DW 00
COL DB 00
DECIND DB 00
MULT10 DW 01
NODEC DW 00
ROW DB 00
SHIFT DW ?
TENWD DW 10
DATASG ENDS
; ----------------------------------------------------
CODESG SEGMENT PARA 'Code'
BEGIN PROC FAR
ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATASG
MOV DS,AX
MOV ES,AX
MOV AX,0600H
CALL Q10SCR ;Очистить экран
CALL Q20CURS ;Установить курсор
A20LOOP:
CALL B10INPT ;Ввести время и расценку
CMP ACTHLEN,00 ;Завершить работу?
JE A30
CALL D10HOUR ;Получить двоичное время
CALL E10RATE ;Получить двоичную расценку
CALL F10MULT ;Расчитать оплату
CALL G10WAGE ;Преобразовать в ASCII
CALL K10DISP ;Выдать результат на экран
JMP A20LOOP
A30:
MOV AX,0600H
CALL Q10SCR ;Очистить экран
RET ;Выйти из программы
BEGIN ENDP
; Ввод времени и расценки
; ----------------------------------------------------
B10INPT PROC
LEA DX,MESSG1 ;Запрос для ввода времени
MOV AH,09
INT 21H
LEA DX,HRSPAR ;Ввести время
MOV AH,0AH
INT 21H
CMP ACTHLEN,00 ;Пустой ввод?
JNE B20
RET ; да - вернуться A20LOOP
B20:
MOV COL,25 ;Установить столбец
CALL Q20CURS
LEA DX,MESSG2 ;Запрос для ввода расценки
MOV AH,09
INT 21H
LEA DX,RATEPAR ;Ввести расценку
MOV AH,0AH
INT 21H
RET
B10INPT ENDP
; Обработка времени:
; -----------------
D10HOUR PROC
MOV NODEC,00
MOV CL,ACTHLEN
SUB CH,CH
LEA SI,HRSFLD-1 ;Установить правую позицию
ADD SI,CX ; времени
CALL M10ASBI ;Преобразовать в двоичное
MOV AX,BINVAL
MOV BINHRS,AX
RET
D10HOUR ENDP
; Обработка расценки:
; ------------------
E10RATE PROC
MOV CL,ACTRLEN
SUB CH,CH
LEA SI,RATEFLD-1 ;Установить правую позицию
ADD SI.CX ; расценки
CALL M10ASBI ;Преобразовать в двоичное
MOV AX,BINVAL
MOV BINRATE,AX
RET
E10RATE ENDP
; Умножение, округление и сдвиг:
; -----------------------------
F10MULT PROC
MOV CX,05
LEA DI,ASCWAGE ;Установить формат оплаты
MOV AX,3030H ; в код ASCII (30)
CLD
REP STOSW
MOV SHIFT,10
MOV ADJUST,00
MOV CX,NODEC
CMP CL,06 ;Если более 6 десятичных
JA F40 ; знаков, то ошибка
DEC CX
DEC CX
JLE F30 ;Обойти, если менее 3 знаков
MOV NODEC,02
MOV AX,01
F20:
MUL TENWD ;Вычислить фактор сдвига
LOOP F20
MOV SHIFT,AX
SHR AX,1 ;Округлить результат
MOV ADJUST,AX
F30:
MOV AX,BINHRS
MUL BINRATE ;Вычислить оплату
ADD AX,ADJUST ;Округлить опла

Список сторінок

Поділитися у соцмережах

☏ Замовлення реклами: +3805044-68-872

© Асоціація електронних бібліотек України

☝ Усі матеріали сайту (зокрема статті, зображення, рекламні оголошення тощо) призначені лише для попереднього ознайомлення. Усі права на публікації, представлені на сайті, належать їхнім законним власникам. Просимо Вас не зберігати копії інформації.