Вычисление выражения по формуле - Assembler (223260)
Формулировка задачи:
Необходимо посчитать след. формулу:
Вот программа, которую собрал из учебника:
Листинг программы
- title prim
- assume cs:cod, ds:d, ss:s
- s segment stack
- dw 128 dup (?)
- s ends
- d segment
- ;резервируем области под переменные a, b, c
- a dw ?
- b dw ?
- c dw ?
- ;размещаем строки – подсказки для ввода переменных
- msga db ‘Введите a:$’
- msgb db ‘Введите b:$’
- msgc db ‘Введите c:$’
- ;размещаем строки – сообщения об ошибках
- err1 db ‘Деление на ноль (первая дробь)$’
- err2 db ‘Деление на ноль (вторая дробь)$’
- ;описываем данные для процедур ввода и вывода целых чисел
- .
- .
- .
- d ends
- c od segment
- ;описываем процедуры ввода и вывода целых чисел
- cr = 0dh ;cr присваиваем значение кода символа
- ;возврата каретки (клавиши «Enter»)
- lf = 0ah ;lf присваиваем значение кода символа
- ;перевода строки
- IntegerIn proc
- start: mov ah,0ah ;функцией 0a вводим строку
- ;символов и размещаем ее в
- ;области string
- lea dx,string
- int 21h
- xor ax,ax ;обнуляем ax, в котором
- ;будем формировать число
- lea si,string+2 ;устанавливаем si на
- ;первый символ введенной
- ;строки
- mov negflag,ax ;обнуляем флаг
- ;отрицательности числа
- ;(предполагаем, что оно
- ;будет неотрицательным)
- cmp byte ptr [si],'-';первый символ – это
- ;минус?
- jne m2 ;если нет – на m2
- not negflag ;отмечаем, что число
- ;отрицательное
- ;(negflag не равен 0)
- inc si ;продвигаем si со
- ;знака числа к первой
- ;цифре
- jmp m ;прыгаем на разбор
- ;строки цифр
- m2: cmp byte ptr [si],'+';первый символ – это
- ;плюс?
- jne m ;если нет – на m
- inc si ;продвигаем si со
- ;знака числа к первой
- ;цифре
- ;анализируем текущий символ
- m: cmp byte ptr [si],cr ;если это cr – строка
- ;закончилась, выходим
- ;из цикла разбора
- ;символов
- je ex1
- cmp byte ptr [si],'0';если код символа
- ;меньше кода '0' –
- ;это не цифра
- jb err ;прыгаем на метку err
- cmp byte ptr [si],'9';если код символа
- ;больше кода '9' –
- ;это не цифра
- ja err ;прыгаем на метку err
- mov bx,10 ;домножаем полученное
- ;число на основание
- ;системы счисления
- mul bx
- sub byte ptr [si],'0';вычитаем код символа
- ;'0' (получаем
- ;очередную цифру)
- add al,[si] ;добавляем цифру к
- ;числу
- adc ah,0
- inc si ;продвигаем si к
- ;следующему символу
- jmp m ;организуем цикл
- ;функцией 09 выводим сообщение об ошибке
- err: lea dx,errmsg
- mov ah,9
- int 21h
- jmp start ;повторяем ввод
- ex1: cmp negflag,0 ;число положительное?
- je ex ;если да – выходим
- neg ax ;меняем знак числа
- ex: ret
- IntegerIn endp
- IntegerOut proc
- xor cx,cx ;обнуляем счетчик цифр
- mov bx,10 ;в bx помещаем делитель
- cmp ax,0 ;проверяем знак числа
- jge m ;если неотрицательное – на m
- neg ax ;иначе – меняем знак числа
- pushax ;сохраняем число перед вызовом
- ;функции, использующей ax
- mov ah,2 ;функцией 02 выводим знак '-'
- mov dl,'-'
- int 21h
- pop ax ;восстанавливаем число в ax
- m: inc cx ;считаем количество
- ;получающихся цифр
- xor dx,dx ;преобразуем делимое к 32
- ;разрядам
- div bx ;получаем очередную цифру
- pushdx ;сохраняем ее в стеке
- or ax,ax ;проверяем есть ли еще цифры
- jnz m ;если да – на метку m
- ;при выходе из цикла в стеке лежат цифры, в cx – их
- ;количество
- m1: pop dx ;извлекаем цифру из стека
- add dx,'0' ;преобразуем в код символа
- mov ah,2 ;функцией 02 выводим на экран
- int 21h
- loopm1 ;повторяем cx раз
- ret ;возвращаемся из процедуры
- IntegerOut endp
- ;устанавливаем ds на сегмент данных
- string db 255, 0, 255 dup (?)
- errmsg db 'Недопустимый символ, можно'
- db 'использовать только цифры',cr,lf,'$'
- start: mov ax,d
- mov ds,ax ;вводим значение переменныой a
- Mov ah,09 ;выводим строку – подсказку для a
- Lea dx,msga
- Int 21h
- Call IntegerIn ;вводим число
- Mov a,ax ;помещаем его в область a
- ;вводим значение переменныой b
- Mov ah,09 ;выводим строку – подсказку для b
- Lea dx,msgb
- Int 21h
- Call IntegerIn ;вводим число
- Mov b,ax ;помещаем его в область b
- ;вводим значение переменныой c
- Mov ah,09 ;выводим строку – подсказку для c
- Lea dx,msgc
- Int 21h
- Call IntegerIn ;вводим число
- Mov c,ax ;помещаем его в область c
- ;проверяем знаменатели на равенство 0
- Cmp c,0 ;проверяем первый знаменатель
- Jnz m ;если не 0 – на m
- Mov ah,09 ;выводим сообщение об ошибке
- Lea dx,err1
- Int 21h
- Jmp err ;выходим
- m: Mov ax,b ;считаем второй знаменатель
- Add ax,c
- Jnz m1 ; если не 0 – на m1
- Mov ah,09 ;выводим сообщение об ошибке
- Lea dx,err2
- Int 21h
- Jmp err ;выходим
- ;рассчитываем значение выражения
- m1: Mov bx,ax ;помещаем второй знаменатель в bx
- Mov ax,a ;считаем второй числитель
- Imul ax
- Mov cx,3
- Imul cx
- Idiv bx ;считаем значение второй дроби
- Push ax ;сохраняем его в стеке
- Mov ax,a ;считаем первый числитель
- Add ax,b
- Mov bx,c ;считаем значение первой дроби
- Cwd
- Idiv bx
- Pop bx ;извлекаем из стека значение второй
- ;дроби
- Sub ax,bx ;вычитаем
- call IntegerOut ;выводим результат
- ;завершаем работу программы
- mov ax,4c00h ;с кодом завершения 0 – без ошибок
- int 21h
- err: mov ax,4cffh ;с кодом завершения 0ffh (-1) – с ошибкой
- int 21h
- c od ends
- end start
Решение задачи: «Вычисление выражения по формуле»
textual
Листинг программы
- title prim
- assume cs:cod, ds:d, ss:s
- LOCALS
- s segment stack
- dw 128 dup (?)
- s ends
- d segment
- ;резервируем области под переменные a, b, c
- a dw ?
- b dw ?
- y dw ?
- ;размещаем строки – подсказки для ввода переменных
- msga db 'Введите a:$'
- msgb db 'Введите b:$'
- ;размещаем строки – сообщения об ошибках
- err1 db 'Деление на ноль (первая дробь)$'
- err2 db 'Деление на ноль (вторая дробь)$'
- ;описываем данные для процедур ввода и вывода целых чисел
- string db 255, 0, 255 dup (?)
- errmsg db 'Недопустимый символ, можно'
- db 'использовать только цифры',cr,lf,'$'
- negflag dw 0
- d ends
- cod segment
- ;описываем процедуры ввода и вывода целых чисел
- cr = 0dh ;cr присваиваем значение кода символа
- ;возврата каретки (клавиши «Enter»)
- lf = 0ah ;lf присваиваем значение кода символа
- ;перевода строки
- IntegerIn proc
- @@start: mov ah,0ah ;функцией 0a вводим строку
- ;символов и размещаем ее в
- ;области string
- lea dx,string
- int 21h
- xor ax,ax ;обнуляем ax, в котором
- ;будем формировать число
- lea si,string+2 ;устанавливаем si на
- ;первый символ введенной
- ;строки
- mov negflag,ax ;обнуляем флаг
- ;отрицательности числа
- ;(предполагаем, что оно
- ;будет неотрицательным)
- cmp byte ptr [si],'-';первый символ – это
- ;минус?
- jne @@m2 ;если нет – на m2
- not negflag ;отмечаем, что число
- ;отрицательное
- ;(negflag не равен 0)
- inc si ;продвигаем si со
- ;знака числа к первой
- ;цифре
- jmp @@m ;прыгаем на разбор
- ;строки цифр
- @@m2: cmp byte ptr [si],'+';первый символ – это
- ;плюс?
- jne @@m ;если нет – на m
- inc si ;продвигаем si со
- ;знака числа к первой
- ;цифре
- ;анализируем текущий символ
- @@m: cmp byte ptr [si],cr ;если это cr – строка
- ;закончилась, выходим
- ;из цикла разбора
- ;символов
- je @@ex1
- cmp byte ptr [si],'0';если код символа
- ;меньше кода '0' –
- ;это не цифра
- jb @@err ;прыгаем на метку err
- cmp byte ptr [si],'9';если код символа
- ;больше кода '9' –
- ;это не цифра
- ja @@err ;прыгаем на метку err
- mov bx,10 ;домножаем полученное
- ;число на основание
- ;системы счисления
- mul bx
- sub byte ptr [si],'0';вычитаем код символа
- ;'0' (получаем
- ;очередную цифру)
- add al,[si] ;добавляем цифру к
- ;числу
- adc ah,0
- inc si ;продвигаем si к
- ;следующему символу
- jmp @@m ;организуем цикл
- ;функцией 09 выводим сообщение об ошибке
- @@err: lea dx,errmsg
- mov ah,9
- int 21h
- jmp @@start ;повторяем ввод
- @@ex1: cmp negflag,0 ;число положительное?
- je @@ex ;если да – выходим
- neg ax ;меняем знак числа
- @@ex: ret
- IntegerIn endp
- IntegerOut proc
- xor cx,cx ;обнуляем счетчик цифр
- mov bx,10 ;в bx помещаем делитель
- cmp ax,0 ;проверяем знак числа
- jge @@m ;если неотрицательное – на m
- neg ax ;иначе – меняем знак числа
- push ax ;сохраняем число перед вызовом
- ;функции, использующей ax
- mov ah,2 ;функцией 02 выводим знак '-'
- mov dl,'-'
- int 21h
- pop ax ;восстанавливаем число в ax
- @@m: inc cx ;считаем количество
- ;получающихся цифр
- xor dx,dx ;преобразуем делимое к 32
- ;разрядам
- div bx ;получаем очередную цифру
- push dx ;сохраняем ее в стеке
- or ax,ax ;проверяем есть ли еще цифры
- jnz @@m ;если да – на метку m
- ;при выходе из цикла в стеке лежат цифры, в cx – их
- ;количество
- @@m1: pop dx ;извлекаем цифру из стека
- add dx,'0' ;преобразуем в код символа
- mov ah,2 ;функцией 02 выводим на экран
- int 21h
- loop @@m1 ;повторяем cx раз
- ret ;возвращаемся из процедуры
- IntegerOut endp
- ;устанавливаем ds на сегмент данных
- start: mov ax,d
- mov ds,ax ;вводим значение переменныой a
- Mov ah,09 ;выводим строку – подсказку для a
- Lea dx,msga
- Int 21h
- Call IntegerIn ;вводим число
- Mov a,ax ;помещаем его в область a
- ;вводим значение переменныой b
- Mov ah,09 ;выводим строку – подсказку для b
- Lea dx,msgb
- Int 21h
- Call IntegerIn ;вводим число
- Mov b,ax ;помещаем его в область b
- mov ax, a
- sub ax, b
- Cmp ax,0 ;проверяем первый знаменатель
- Jnz m ;если не 0 – на m
- Mov ah,09 ;выводим сообщение об ошибке
- Lea dx,err1
- Int 21h
- Jmp error ;выходим
- m: Mov ax,a ;считаем второй знаменатель
- Add ax,b
- Jnz m1 ; если не 0 – на m1
- Mov ah,09 ;выводим сообщение об ошибке
- Lea dx,err2
- Int 21h
- Jmp error ;выходим
- ;рассчитываем значение выражения
- m1: Mov ax, a
- imul a ;ax:=a^2
- Imul b
- Imul b
- Imul b ;ax:=a^2*b^3
- mov bx,3
- imul bx ;ax:=3*a^2*b^3
- add ax, 1 ;ax:=3*a^2*b^3+1
- cwd
- mov bx, a ;bx:=a-b
- sub bx, b
- idiv bx ;ax:=(a^2*b^3+1)/(a-b)
- mov cx,ax ;сохранение значения первой дроби в cx
- Mov ax,a
- sal ax,1
- sal ax,1 ;ax:=a/4
- add ax,b ;ax:=a/4+b
- mov bx,a
- add bx,b
- Idiv bx ;считаем значение второй дроби
- Sub cx,ax ;вычитаем
- mov ax,cx
- call IntegerOut ;выводим результат
- ;завершаем работу программы
- mov ax,4c00h ;с кодом завершения 0 – без ошибок
- int 21h
- error: mov ax,4cffh ;с кодом завершения 0ffh (-1) – с ошибкой
- int 21h
- cod ends
- end start
Объяснение кода листинга программы
В данном коде происходит вычисление выражения по формуле a^2*b^3+1/(a-b). Список действий:
- Ввод значений переменных a и b с помощью процедуры IntegerIn.
- Проверка значения первого знаменателя (a) на ноль. Если он равен нулю, выводится сообщение об ошибке и происходит переход на метку m.
- Вычисление второго знаменателя (b) и проверка его значения на ноль. Если он равен нулю, также выводится сообщение об ошибке и происходит переход на метку m.
- Вычисление значения выражения по формуле a^2*b^3+1/(a-b).
- Сохранение значения первой дроби (a^2*b^3+1) в переменной cx.
- Вычисление значения второй дроби (a/4+b) и вычитание ее из значения первой дроби (cx).
- Вывод результата вычисления на экран с помощью процедуры IntegerOut.
- Завершение работы программы с кодом завершения 0 (без ошибок) или 0ffh (-1) (с ошибкой), в зависимости от наличия ошибок в процессе выполнения программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д