Деление чисел - Assembler (223561)
Формулировка задачи:
Надо найти результат деления двух целых пятизначных чисел, которые представлены в десятичном формате. Числа ввести с клавиатуры, результат вывести в виде Z = XXX . XXX (целая часть.дробная часть).
Написал ввод с клавиатуры и некое подобие вывода на экран, а вот с делением пятизначных не очень понимаю, ведь у нас число может быть до 65535, а если пользователь введет 99999? В общем, помогите, пожалуйста.
.model small
.stack 16h
.data
msgA db 'Enter A = ', '$ '
msgB db 13,10,'Enter B = ', '$ '
msg label byte ;массив для ввода символов
maxnum db 6 ;длина массива
reallen db ?
numfld db 5 dup(30h)
mult10 dw 0
ascval db 10 dup(30h),13,10,'$' ;массив символов для вывода*
x dw ? ;результат
a dw 0 ;коэффициенты
b dw 0
z dw 0
.code
start: mov ax, @data
mov ds, ax
mov ah,9
lea dx, msgA
int 21H; просим ввести A
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov a,ax ; вводим A
mov ah,9
lea dx, msgB
int 21H; просим ввести И
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov b,ax ; вводим B
;здесь должны быть вычисления
call outp ; вывод результата на экран
mov ah, 4ch
int 21h
asbin proc ; запись с клавиатуры
mov mult10,0001
mov z,0
mov cx,10
lea si,numfld-1
mov bl,reallen
sub bh,bh
b20:
mov al,[si+bx]
and ax,000fh
mul mult10
add z,ax
mov ax,mult10
mul cx
mov mult10,ax
dec bx
jnz b20
ret
asbin endp
outp proc ; Начало тела процедуры "вывод"
mov cx,10 ; система счисления
lea si, ascval+9 ; Установка указателя на конец массива ascval
mov ax, x ; Результат х занести в ax
c20: cmp ax,10 ; Сравнить результат с числом 10
jb c30 ; Если меньше то преобразовывать не надо
xor dx,dx ; Очистка регистра dx для команды деления
div cx ; Делим на 10
or dl, 30h ; Преобразование остатка к ASCII коду
mov [si], dl ; Занесение остатка от деления в массив ascval
dec si ; Перемещение указателя массива на 1 байт влево
jmp c20 ; Переход на начало для преобразования след. цифры
c30: or al, 30h ; Если остаток меньше 10, то вывод результата на экран
mov [si], al ; дисплея командами (см. ниже)
lea dx, ascval ; Загрузка адреса массива
mov ah, 9 ; Вызов 9-ой функции MS-DOS
int 21h
ret ; Возврат в головную программу из п/программы
outp endp ; Конец процедуры
end start
Вот уже даже с делением, но больше 32000 он не принимает
.model small
.stack 16h
.data
msgA db 'Enter A = ', '$ '
msgB db 13,10,'Enter B = ', '$ '
msg5 db 13,10,'Result X = ', '$ '
msg label byte ;массив для ввода символов
maxnum db 6 ;длина массива
reallen db ?
numfld db 5 dup(30h)
mult10 dw 0
ascval db 10 dup(30h),13,10,'$' ;массив символов для вывода*
x dw ? ;результат
a dw 0 ;коэффициенты
b dw 0
z dw 0
.code
start: mov ax, @data
mov ds, ax
mov ah,9
lea dx, msgA
int 21H;
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov a,ax
mov ah,9
lea dx, msgB
int 21H;
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov b,ax
mov ah,9
lea dx, msg5
int 21H;
mov bx, dx
mov cx, ax
mov ax, a
mov dx,0
idiv b
mov x, ax
call outp ; вывод результата на экран
mov ah, 4ch
int 21h
asbin proc
mov mult10,0001
mov z,0
mov cx,10
lea si,numfld-1
mov bl,reallen
sub bh,bh
b20:
mov al,[si+bx]
and ax,000fh
mul mult10
add z,ax
mov ax,mult10
mul cx
mov mult10,ax
dec bx
jnz b20
ret
asbin endp
outp proc ; Начало тела процедуры "вывод"
mov cx,10 ; система счисления
lea si, ascval+9 ; Установка указателя на конец массива ascval
mov ax, x ; Результат х занести в ax
c20: cmp ax,10 ; Сравнить результат с числом 10
jb c30 ; Если меньше то преобразовывать не надо
xor dx,dx ; Очистка регистра dx для команды деления
div cx ; Делим на 10
or dl, 30h ; Преобразование остатка к ASCII коду
mov [si], dl ; Занесение остатка от деления в массив ascval
dec si ; Перемещение указателя массива на 1 байт влево
jmp c20 ; Переход на начало для преобразования след. цифры
c30: or al, 30h ; Если остаток меньше 10, то вывод результата на экран
mov [si], al ; дисплея командами (см. ниже)
lea dx, ascval ; Загрузка адреса массива
mov ah, 9 ; Вызов 9-ой функции MS-DOS
int 21h
ret ; Возврат в головную программу из п/программы
outp endp ; Конец процедуры
end start
Теперь до 65000
.model small
.stack 16h
.data
msgA db 'Enter A = ', '$ '
msgB db 13,10,'Enter B = ', '$ '
msg5 db 13,10,'Result X = ', '$ '
msg label byte ;массив для ввода символов
maxnum db 6 ;длина массива
reallen db ?
numfld db 5 dup(30h)
mult10 dw 0
ascval db 10 dup(30h),13,10,'$' ;массив символов для вывода*
x dw ? ;результат
a dw 0 ;коэффициенты
b dw 0
c dw 1000
z dw 0
u dw 0
.code
start: mov ax, @data
mov ds, ax
mov ah,9
lea dx, msgA
int 21H;
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov a,ax
mov ah,9
lea dx, msgB
int 21H;
mov ah,0AH
lea dx,msg
int 21H
call asbin
mov ax,z
mov b,ax
mov ah,9
lea dx, msg5
int 21H;
mov bx, dx
mov cx, ax
xor dx,dx
mov ax, a
idiv b
mov x, ax
;mov ax,dx
;imul c
;idiv x
;mov u,ax
call outp ; вывод результата на экран
mov ah, 4ch
int 21h
asbin proc
mov mult10,0001
mov z,0
mov cx,10
lea si,numfld-1
mov bl,reallen
sub bh,bh
b20:
mov al,[si+bx]
and ax,000fh
mul mult10
add z,ax
mov ax,mult10
mul cx
mov mult10,ax
dec bx
jnz b20
ret
asbin endp
outp proc ; Начало тела процедуры "вывод"
mov cx,10 ; система счисления
lea si, ascval+9 ; Установка указателя на конец массива ascval
mov ax, x ; Результат х занести в ax
c20: cmp ax,10 ; Сравнить результат с числом 10
jb c30 ; Если меньше то преобразовывать не надо
xor dx,dx ; Очистка регистра dx для команды деления
div cx ; Делим на 10
or dl, 30h ; Преобразование остатка к ASCII коду
mov [si], dl ; Занесение остатка от деления в массив ascval
dec si ; Перемещение указателя массива на 1 байт влево
jmp c20 ; Переход на начало для преобразования след. цифры
c30: or al, 30h ; Если остаток меньше 10, то вывод результата на экран
mov [si], al ; дисплея командами (см. ниже)
lea dx, ascval ; Загрузка адреса массива
mov ah, 9 ; Вызов 9-ой функции MS-DOS
int 21h
ret ; Возврат в головную программу из п/программы
outp endp ; Конец процедуры
end startРешение задачи: «Деление чисел»
textual
Листинг программы
asbin proc ; Процедура ввода с клавиатуры mov mult10,0001 mov z,0 mov cx,10 lea si,numfld-1 mov bl,reallen sub bh,bh b20: mov al,[si+bx] and ax,000fh mul mult10 cmp ax,'-' ;если минус, то jne b30 mov dh,1 ;устанавливаем признак минуса sub ax,'-' jmp b20 b30: add z,ax mov ax,mult10 mul cx mov mult10,ax dec bx jnz b20 test dh,dh ;если установлен признак отрицательного числа jne b40 neg z ;то меняем знак b40: ret asbin endp
Объяснение кода листинга программы
- Процедура ввода с клавиатуры.
- Переменная mult10 содержит значение 10.
- Переменная z содержит результат деления.
- Переменная cx содержит количество разрядов числа.
- Переменная si содержит адрес поля ввода числа.
- Переменная bl содержит значение реального числа.
- Переменная bh содержит знак реального числа.
- Переменная ax содержит результат операции.
- Переменная dh содержит признак отрицательного числа.
- Переменная numfld содержит адрес поля ввода числа.
- При выходе из процедуры ввода, значение переменной z обновляется.
- Если введенное число отрицательное, то устанавливается признак отрицательного числа.
- Результат деления сохраняется в переменной z.
- Если введенное число не является числом, то процедура продолжается до тех пор, пока не будет введено число.
- Результат умножения числа на 10 сохраняется в переменной ax.
- Переменная mult10 обновляется значением ax.
- Уменьшается значение переменной bx на единицу.
- Если значение переменной bx больше нуля, то процедура продолжается до тех пор, пока не будет введено число.
- Если введенное число является отрицательным, то результат деления изменяется на противоположный.
- Конец процедуры ввода с клавиатуры.