Запись числа прописью - Assembler

Узнай цену своей работы

Формулировка задачи:

Перевод числа из десятичной формы (<255) в прописную Написать программу, которая вводит и и записывает(выводит)однобайтовое целое число без знака прописью, например 128 = сто двадцать восемь. Был бы рад любой помощи, он полной до частичной, а иначе меня ждет призыв летний в армию. Думаю разницы нет, но компилировать могу в FASM. И EMY8086.

Решение задачи: «Запись числа прописью»

textual
Листинг программы
LOCALS
 
.model small
 
.stack 100h
 
.data
        CrLf    db      0Dh, 0Ah, '$'
 
        _100    db      'сто', '$'
        _200    db      'двести', '$'
        _20     db      'двадцать', '$'
        _30     db      'тридцать', '$'
        _40     db      'сорок', '$'
        _50     db      'пятьдесят', '$'
        _60     db      'шестьдесят', '$'
        _70     db      'семьдесят', '$'
        _80     db      'восемьдесят', '$'
        _90     db      'девяносто', '$'
        _10     db      'десять', '$'
        _11     db      'одиннадцать', '$'
        _12     db      'двенадцать', '$'
        _13     db      'тринадцать', '$'
        _14     db      'четырнадцать', '$'
        _15     db      'пятнадцать', '$'
        _16     db      'шестнадцать', '$'
        _17     db      'семнадцать', '$'
        _18     db      'восемнадцать', '$'
        _19     db      'девятнадцать', '$'
        _0      db      'ноль', '$'
        _1      db      'один', '$'
        _2      db      'два', '$'
        _3      db      'три', '$'
        _4      db      'четыре', '$'
        _5      db      'пять', '$'
        _6      db      'шесть', '$'
        _7      db      'семь', '$'
        _8      db      'восемь', '$'
        _9      db      'девять', '$'
 
        hundreds        label
                dw      offset  _100
                dw      offset  _200
        dozens2         label
                dw      offset  _20
                dw      offset  _30
                dw      offset  _40
                dw      offset  _50
                dw      offset  _60
                dw      offset  _70
                dw      offset  _80
                dw      offset  _90
        dozens1         label
                dw      offset  _10
                dw      offset  _11
                dw      offset  _12
                dw      offset  _13
                dw      offset  _14
                dw      offset  _15
                dw      offset  _16
                dw      offset  _17
                dw      offset  _18
                dw      offset  _19
        units           label
                dw      offset  _0
                dw      offset  _1
                dw      offset  _2
                dw      offset  _3
                dw      offset  _4
                dw      offset  _5
                dw      offset  _6
                dw      offset  _7
                dw      offset  _8
                dw      offset  _9
 
        N       db      0
 
        kbdBuf  db      4, 0, 4 dup(0)
        Prompt  db      'Input number: ', '$'
.code
 
main    proc
        mov     ax,     @data
        mov     ds,     ax
 
        ;ввод числа в виде строки
        mov     ah,     09h
        lea     dx,     Prompt
        int     21h
        mov     ah,     0Ah
        lea     dx,     kbdBuf
        int     21h
        mov     ah,     09h
        lea     dx,     CrLf
        int     21h
        ;преобразования строки в число
        lea     si,     kbdBuf+1
        call    StrToUInt8
        mov     N,      al
 
        ;получение числа прописью
        mov     ax,     0
        mov     al,     N
        mov     ch,     1       ;число равно нулю
@@Hundreds:
        mov     cl,     100
        div     cl
        cmp     al,     0
        je      @@Dozens
        mov     ch,     0       ;не нужно выводить "ноль"
        lea     si,     Hundreds
        mov     bx,     0
        mov     bl,     al
        dec     bx
        add     bx,     bx
        mov     dx,     [si+bx]
        push    ax
        mov     ah,     09h
        int     21h
        mov     ah,     02h
        mov     dl,     ' '
        int     21h
        pop     ax
@@Dozens:
        cmp     ah,     20
        jae     @@Dozens2
        cmp     ah,     10
        jb      @@Dozens2
        lea     si,     Dozens1
        mov     bx,     0
        mov     bl,     ah
        sub     bx,     10
        add     bx,     bx
        mov     dx,     [si+bx]
        push    ax
        mov     ah,     09h
        int     21h
        mov     ah,     02h
        mov     dl,     ' '
        int     21h
        pop     ax
        jmp     @@Exit
 
@@Dozens2:
        mov     al,     ah
        mov     ah,     0
        mov     cl,     10
        div     cl
        cmp     al,     0
        je      @@Units
        mov     ch,     0
        lea     si,     Dozens2
        mov     bx,     0
        mov     bl,     al
        sub     bx,     2
        add     bx,     bx
        mov     dx,     [si+bx]
        push    ax
        mov     ah,     09h
        int     21h
        mov     ah,     02h
        mov     dl,     ' '
        int     21h
        pop     ax
@@Units:
        ;требуется выводить ноль?
        or      ch,     ah
        jz      @@Exit
        lea     si,     Units
        mov     bx,     0
        mov     bl,     ah
        add     bx,     bx
        mov     dx,     [si+bx]
        push    ax
        mov     ah,     09h
        int     21h
        pop     ax
 
 
 
@@Exit:
        mov     ax,     4C00h
        int     21h
main    endp
 
;Преобразование строки Pascal типа в беззнаковое число размером 1 байт
;на входе:
;  ds:si - указатель на строку Pascal типа
;на выходе:
;  al - считанное число
;  ah=0
StrToUInt8      proc
        push    bx
        push    cx
        push    dx
        push    si
        push    di
 
        mov     ax,     0       ;итоговое число
        mov     cx,     0       ;количество символов в строке
        mov     cl,     [si]
        mov     bx,     10      ;множитель
        inc     si              ;si - теперь указывает на символьный массив
        jcxz    @@Exit
@@For:
        mul     bl              ;ax=al*10
        cmp     ah,     0       ; проверяем, результат на переполнение
        jne     @@Error
        mov     di,     ax      ;сохраняем промежуточный результат
 
        mov     al,     [si]    ; Преобразуем следующий символ в число
        ;проверка, что символ - цифра
        cmp     al,     '0'
        jb      @@Error
        cmp     al,     '9'
        ja      @@Error
        ;преобразование символа цифры в число
        sub     al,     '0'
        add     ax,     di      ;
        cmp     ah,     0       ; проверяем, результат на переполнение
        jne     @@Error
 
        inc     si
        loop    @@For
 
        clc                     ;нет ошибки
        jmp     @@Exit
@@Error:
        mov     ax,     0
        stc                     ;признак ошибки
@@Exit:
        pop     di
        pop     si
        pop     dx
        pop     cx
        pop     bx
        ret
StrToUInt8      endp
 
end     main

Объяснение кода листинга программы

  1. Создание переменных:
    • CrLf - байтовая последовательность для перевода строки в консоли
    • _100, _200, _20, _30, _40, _50, _60, _70, _80, _90, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9 - строковые переменные, содержащие числительные
    • hundreds, dozens2, dozens1, units - метки
    • N - байтовая переменная для хранения числа
    • kbdBuf - массив байтов для ввода числа в виде строки
    • Prompt - строка для приглашения ввести число
  2. Ввод числа:
    • Вывод приглашения ввести число
    • Считывание числа в виде строки
    • Преобразование строки в число
  3. Преобразование числа в числительное:
    • Определение сотен, десятков и единиц в числе и вывод их названий в консоль
  4. Обработка ошибок и завершение программы. *примечание: указанный код написан на ассемблере, который приближен к x86 Assembly.

Оцени полезность:

8   голосов , оценка 4.5 из 5
Похожие ответы