Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [Assembler] Перемножение чисел


Автор: Гениальный123Робот 30.1.2007, 15:59
Написать подпрограммы для ввода и вывода десятичных чисел. В главной программе необходимо ввести два числа при помощи этих подпрограмм, перемножить эти числа и вывести результат на экран.

Спасибо заранее. Очень надо бы. 

Автор: anwe 28.2.2007, 14:30
Держи. Можно вводить и отрицательные числа.
Код

    model    tiny
    .286
    .code
    org    100h
start:
    mov    dx,offset prigl
    mov    ah,09h
    int    21h
    call    podprog
    cmp    byte ptr prigl[0],'z'
    je    lend
    push    ax
    mov    dx,offset perevod
    mov    ah,09h
    int    21h
    mov    byte ptr prigl[15],'2'
    mov    dx, offset prigl
    int    21h
    call    podprog
    cmp    byte ptr prigl[0],'z'
    je    lend1
    push    ax
    mov    dx,offset perevod
    mov    ah,09h
    int    21h
    pop    ax
    pop    bx
    add    ax,bx
    push    ax
    xchg    ah,al
    call    prn
    pop    ax
    call    prn
lend:
    ret
lend1:
    pop    ax
    ret
;--------------------
prn    proc    near
    mov    dh,al
    and    dh,0Fh
    shr    al,4
    call    print
    mov    al,dh
print:
    cmp    al,10
    sbb    al,69h
    das
    mov    dl,al
    mov    ah,02
    int    21h
    ret
endp    prn
;--------------------
podprog    proc    near
    mov    dx,offset buf
    mov    ah,0Ah
    int    21h
    cmp    byte ptr z[0],'-'
    jne    l2
    mov    di,1
    jmp    l3
l2:
    xor    di,di
l3:
    xor    ax,ax
    mov    cl,len
    xor    ch,ch
    mov    si,cx
    xor    bx,bx
    mov    cl,10
l1:
    mov    bl,byte ptr z[di]
    sub    bl,'0'
    jb    lerror
    cmp    bl,9
    ja    lerror
    mul    cx
    add    ax,bx
    inc    di
    cmp    di,si
    jb    l1
    cmp    byte ptr z[0],'-'
    jne    l4
    neg    ax
l4:
    ret
lerror:
    mov    dx,offset perevod
    mov    ah,09h
    int    21h
    mov    dx,offset ermes
    int    21h
    mov    byte ptr prigl[0],'z'
    ret
endp    podprog

prigl    db    'Vvedite chislo 1: ','$'
ermes    db    'Ne vernoe chislo!','$'
perevod    db    0Dh,0Ah,'$'
buf    db    6
len    db    ?
z:
end    start

Автор: Гениальный123Робот 28.2.2007, 23:23
Спасибо огромное! Также поясни ключевые моменты. ;) Желательно побольше! Я вот только начал читать первые страницы книги...
Благодарен. 

Автор: anwe 28.2.2007, 23:45
Код

    model    tiny
    .286
    .code
    org    100h
start:
    mov    dx,offset prigl        ;вывод приглашения
    mov    ah,09h
    int    21h
    call    podprog            ;вызов подпрограммы ввода
    cmp    byte ptr prigl[0],'z'    ;если вместо первого v стоит z, значит
    je    lend            ;было введено нечисло - выход
    push    ax            ;сохранить полученное число
    mov    dx,offset perevod    ;перевод строки
    mov    ah,09h
    int    21h
    mov    byte ptr prigl[15],'2'    ;подкорректировать приглашение для 2 числа
    mov    dx, offset prigl    ;вывод его
    int    21h
    call    podprog
    cmp    byte ptr prigl[0],'z'
    je    lend1
    push    ax
    mov    dx,offset perevod
    mov    ah,09h
    int    21h
    pop    ax            ;восстановить второе число
    pop    bx            ;восстановить первое число
    add    ax,bx            ;сложить их
    push    ax            ;сохранить результат
    xchg    ah,al            ;обмен байтами
    call    prn            ;сначала вывод старшего байта
    pop    ax            ;восстановить результат
    call    prn            ;теперь вывод младшего байта
lend:
    ret
lend1:
    pop    ax            ;необходимо очистить стек от 1 числа
    ret
;--------------------
prn    proc    near
    mov    dh,al            ;сохранить результат
    and    dh,0Fh            ;оставить лишь младший полубайт
    shr    al,4            ;оставить лишь старший полубайт
    call    print            ;сначала вывод страшего полубайта
    mov    al,dh            ;восстановить результат
print:                    ;теперь - младшего полубайта
    cmp    al,10            ;три строки перевода цифры в ее код
    sbb    al,69h
    das
    mov    dl,al            ;функция вывода символа
    mov    ah,02
    int    21h
    ret
endp    prn
;--------------------
podprog    proc    near
    mov    dx,offset buf        ;считать введеное число в буфер
    mov    ah,0Ah
    int    21h
    cmp    byte ptr z[0],'-'    ;1 символ = -?
    jne    l2
    mov    di,1            ;да - занести в счетчик символов 1
    jmp    l3
l2:
    xor    di,di            ;нет - занести в счетчик символов 0
l3:
    xor    ax,ax            ;здесь будет результат
    mov    cl,len            ;здесь длина введенной строки
    xor    ch,ch
    mov    si,cx            ;она храниться в si
    xor    bx,bx            ;сюда считываем очередной символ
    mov    cl,10            ;десятичный множитель
l1:
    mov    bl,byte ptr z[di]    ;считать символ
    sub    bl,'0'            ;скорректировать под цифру 0
    jb    lerror            ;меньше - ошибка
    cmp    bl,9            ;сравнить с 9
    ja    lerror            ;больше - ошибка
    mul    cx            ;домножить
    add    ax,bx            ;добавить к полученному
    inc    di            ;увеличить счетчик
    cmp    di,si            ;равен длине строке?
    jb    l1            ;нет - повтор
    cmp    byte ptr z[0],'-'    ;да - первый символ - ?
    jne    l4            ;нет - выход
    neg    ax            ;да - обратить результат
l4:
    ret
lerror:
    mov    dx,offset perevod
    mov    ah,09h
    int    21h
    mov    dx,offset ermes        ;вывод сообщения об ошибке ввода
    int    21h
    mov    byte ptr prigl[0],'z'    ;ввести признак ввода нечисла
    ret
endp    podprog

prigl    db    'Vvedite chislo 1: ','$'
ermes    db    'Ne vernoe chislo!','$'
perevod    db    0Dh,0Ah,'$'
buf    db    6
len    db    ?
z:
end    start

Ничего сложного нет, только что признаком ввода нечисла (любого набора символов) является первый символ приглашения V, которая меняется на z. Это просто хитренький способ не вводить еще одну переменную, экономя лишний байт памяти. smile 
И еще если введено нечисло второй раз, то сначала надо очистить стек, в котором сохранен первый результат.

Автор: Гениальный123Робот 1.3.2007, 18:45
anwe, окей. спасибо. 
Начинаю вникать и пониматься. А тебе вот еще задачка к этой же задаче: 
Модифицировать подпрограммы второй лабораторной (данной выше) работы таким образом, чтобы можно было вводить и выводить знаковые числа.
Создай новый топ, если решишь (модифицируешь). 
P.S. Я сюда для наглядности скинул...
P.P.S. Спасибо за помощь

Автор: anwe 1.3.2007, 19:59
А ты смотрел мой первый ответ:
Цитата(anwe @  28.2.2007,  13:30 Найти цитируемый пост)
Можно вводить и отрицательные числа


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)