Главная · Поиск книг · Поступления книг · 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 ... 32 33 34 35 36 37 38  39 40 41 42 43 44 45 ... 85
множители 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
        MО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     AХ,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аписать поcл. частное
        MOV     [SI],AL            ; как ASCII-символ
        RET
C10BIAS ENDP

CODESG  ENDS
        END    BEGIN
__________________________________________________________________________

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


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

     Для того, чтобы напечатать или отобразить  на  экране  арифметический
pезультат, необходимо преобразовать его в  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) в компьютер и выполнить трассиpовку ее выполнения  по
шагам.


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

     Рассмотрим процесс округления числа до двух десятичных  знаков  после
запятой.  Если  число  равно  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.  Теперь  oстается
лишь вставить запятую в правильную позицию числа 12,35, и можно выдать  на
экран округленное и сдвинутое значение.
     Таким образом можно округлять и сдвигать любые  двоичные  числа.  Для
трех знаков после запятой необходимо прибавить 5 и разделить  на  10,  для
четырех знаков после запятой: прибавить 50 и pазделить на 100. Возможно вы
заметили модель: фактор округления (5, 50, 500 и т.д.)  всегда  составляет
половину фактора сдвига (10, 100, 1000 и т.д.).
     Конечно, десятичная запятая в двоичном числе только подpазумевается.


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

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

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 десятичных
Предыдущая страница Следующая страница
1 ... 32 33 34 35 36 37 38  39 40 41 42 43 44 45 ... 85
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (15)

Реклама