Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .model small, stdcall
- .data
- sum dw 1000 dup (0)
- crlf db 13,10,'$'
- msg1 db 'Input number: $'
- buf db 8,10 dup(0) ;принимает строку, введенную с клавиатуры
- .stack 1024
- .code
- start:
- mov ax,@data ;Настраиваем сегментные регистры
- mov ds,ax
- mov ah,9 ;функция вывода сообщения на экран
- lea dx,msg1 ;выводимое сообщение
- int 21h ;выводим на экран
- mov ah,0ah ;функция ввода строки с клавиатуры
- mov dx,offset buf ;буфер куда вводить
- int 21h ;пользователь вводит в текстовом виде в buf значение числа
- lea si,buf[2] ;начало введенного текста
- ;Преобразование строки в число
- ;на входе ds:si ссылается на ASCII строку, которую нужно преобразовать
- ;на выходе в ax - число.
- xor dx,dx ;сумма
- @lp1: xor ax,ax
- lodsb ;берем символ
- cmp al,13 ;если это конец строки,
- jz @ex ;то заканчиваем
- cmp al,'9' ;если это не цифра,
- jnbe @lp1 ;то пропускаем
- cmp al,'0' ;если это не цифра,
- jb @lp1 ;то пропускаем
- sub ax,'0' ;получаем цифровое значение
- shl dx,1 ;умножаем сумму на 10
- add ax, dx
- shl dx, 2
- add dx, ax ;прибавляем текущее значение
- jmp @lp1 ;продолжаем обработку
- @ex: mov di,dx ;помещаем результат в di
- mov ah,9 ;функция вывода сообщения на экран
- lea dx,crlf ;выводимое сообщение
- int 21h ;выводим на экран
- call print,di,0,0
- mov ah,1 ;Ожидаем нажатия любой клавиши
- int 21h
- mov ax,4c00h ;закончить программу
- int 21h
- ;left - остаток числа
- ;min - минимальное число разложения
- ;i - индекс числа в массиве
- print proc left:word, min:word, i:word
- cmp left,0 ;если остаток числа 0
- jl fp ;закончить разложение
- cmp min,di ;если минимальное число суммы=самому числу
- jz fp ;закончить разложение
- mov bx,i ;индекс числа
- shl bx,1 ;получить смещение в массиве
- mov ax,min ;взять минимальное число разложения
- mov sum[bx],ax ;и сохранить в массиве под i-м индексом
- cmp min,0 ;если минимальное число разложения=0
- jz sk1 ;то пропустить
- mov ax,left ;остаток числа
- sub ax,min ;остаток числа-минимальное число разложения
- mov cx,i ;индекс числа в массиве
- inc cx ;i+1
- call print,ax,min,cx ;print(left - min, min, i + 1);
- sk1: mov ax,left ;остаток числа
- dec ax ;left - 1
- mov cx,min ;min
- inc cx ;min+1
- call print,ax,cx,i ;print(left - 1, min + 1, i);
- cmp left,0 ;если остаток не 0
- jnz fp ;то пропустить
- ;если 0, вывести полученный массив слагаемых
- lea bx,sum ;начало массива A
- mov cx,0 ;текущий индекс массива (j)
- outmas: cmp cx,i ;если j>i
- ja sk2 ;то закончить вывод
- mov ax,[bx] ;берем элемент массива
- call printdec ;преобразовываем число в строку и выводим
- cmp cx,i ;если это последнее слагаемое
- jz sk3 ;то не выводим +
- mov ah,2 ;выводим символ
- mov dl,'+' ;разделительный +
- int 21h ;выводим
- sk3: add bx,2 ;переходим к следующему элементу массива
- inc cx ;увеличить индекс
- jmp outmas ;продолжаем вывод
- sk2: mov ah,9 ;функция вывода сообщения на экран
- lea dx,crlf ;выводимое сообщение
- int 21h ;выводим на экран
- fp: ret
- print endp
- ;преобразование числа из ах в десятичную строку и вывод на экран
- ;ax - число
- printdec proc
- push cx ;сохраняем регистры
- push dx
- push bx
- mov bx,10 ;основание системы
- xor cx,cx ;в сх будет количество цифр в десятичном числе
- @@m1a: xor dx,dx ;очистить старшую часть делимого
- div bx ;делим число на степени 10
- push dx ;и сохраняем остаток от деления(коэффициенты при степенях) в стек
- inc cx ;увеличиваем количество десятичных цифр числа
- test ax,ax ;после деления остался 0?
- jnz @@m1a ;если нет, продолжаем
- mov ah,2 ;ф-я вывода символа
- @@m2a: pop dx ;взять из стека цифру цисла
- add dl,'0' ;преобразовываем цифру в ASCII символ
- int 21h ;вывести на экран
- loop @@m2a ;все цифры
- pop bx ;восстанавливаем регистры
- pop dx
- pop cx
- ret ;выход из подпрограммы
- printdec endp
- end start
Advertisement
Add Comment
Please, Sign In to add comment