Marat087 » 27 окт 2008, 20:18
Продолжение
Код: Выделить всё
;Вычисление выражения:
xor AX,AX
mov AL, a ;помещаем в АL множитель a
cmp AX, 0
jne dalee_1
mov AH, 09h
lea DX, MsgErr
int 21h
jmp dalee
dalee_1:
mov AL, c ;помещаем в AL с
imul x ;умножаем на х
mov BX, AX ;переноси результат из АХ в ВХ
mov AX, 2807 ;помещаем в АХ число 2807
cbw
imul b ;умножаем на b
sub AX, BX ;вычитаем
push AX ;заносим числитель в стек
mov AL, a ;помещаем в AL а
cbw
imul a ;возводим в квадрат
mov BX, AX ;переноси результат из АХ в ВХ
pop AX ;достаем из стека числитель
cwd ;расширяем числитель до двойного слова DX:AX
idiv BX ;делим числитель на знаменатель в АХ-целая часть, в DX-остаток
push BX
push DX
push AX
mov AX, 135
imul x
mov BX, AX ;перемещаем DX:AX в CX:BX
mov CX, DX
pop AX ;достаем из стека целую часть дроби
cwd ;расширяем её до двойного слова DX:AX
add AX, BX ;складываем с ранее найденным произведением
adc DX, CX
;После вычислений в DX:AX-целая часть результата, в стеке DX-остаток от деления и ВХ-знаменатель дроби
;Конвертируем DX:AX в строку десятичных цифр
mov SI, DX ; сохраняем старшее слово в SI
mov BX, 10 ; делитель
mov CX, SP ; в СХ запоминаем вершину стека
big:
cmp DX, BX ; Войдёт ли результат деления в 16 бит?
jb smal ; да, DX < BX, так что результат уместится в AX!
xchg AX, SI ; старшее слово - в AX, сохраняем младшее слово в SI
xor DX, DX ; обнуляем DX
div BX ; делим старшее слово, остаток помещается в DX
xchg AX, SI ; меняем обратно
div BX ; делим младшее слово
push DX ; сохраняем остаток (0..9) в стек!
mov DX, SI ; prepare for next round
jmp big
smal: ; Remainder fits in lower 16 bits (AX)
div bx ; Divide, result stays in AX, remainder in DX
push dx ; Save remainder
xor dx,dx ; Prepare for next round
test ax,ax ; Any more digits?
jnz smal
; Все цифры собраны в стеке, теперь выводим их в строку:
mov DI, offset bufout
store:
pop ax
add al,'0'
mov [di],al
inc di
cmp cx,sp
jne store
mov al, '$'
mov [DI], al
mov AH, 09h
mov DX, offset bufout
int 21h
vixod:
mov AH, 4Ch ;номер функции 21-го прерывания*
int 21h ;передача управления в DOS
conv proc
mov DI, 0
lea BX, buf+1 ;В ВХ адрес второго элемента буфера
mov CX, [BX] ;в СХ кол-во введённых символов
xor CH, CH ;Обнуляем СН
mov SI, 1 ;в SI множитель
met:
push SI ;сохраняем SI (множитель) в стеке
mov SI, CX ;в SI помещаем номер текущего символа
mov AX, [BX+SI] ;в АХ помещаем текущий символ
xor AH, AH ;обнуляем АН
pop SI ;Извлекаем множитель (SI) из стека
sub AX, 30h ;получаем из символа (АХ) цифру
mul SI ;умножаем цифру (АХ) на множитель (SI)
add DI, AX ;складываем с результирующим числом
mov AX, SI ;помещаем множитель (SI) в АХ
mul m ;увеличиваем множитель (АХ) в 10 раз
mov SI, AX ;перемещаем множитель (АХ) назад в SI
loop met ;переходим к предыдущему символу
mov AH, 09h
lea DX, probel
int 21h
mov DX, DI
ret
conv endp
CodeSg ends; конец сегмента кода
end Bxod; конец программы с точкой входа
Продолжение
[code];Вычисление выражения:
xor AX,AX
mov AL, a ;помещаем в АL множитель a
cmp AX, 0
jne dalee_1
mov AH, 09h
lea DX, MsgErr
int 21h
jmp dalee
dalee_1:
mov AL, c ;помещаем в AL с
imul x ;умножаем на х
mov BX, AX ;переноси результат из АХ в ВХ
mov AX, 2807 ;помещаем в АХ число 2807
cbw
imul b ;умножаем на b
sub AX, BX ;вычитаем
push AX ;заносим числитель в стек
mov AL, a ;помещаем в AL а
cbw
imul a ;возводим в квадрат
mov BX, AX ;переноси результат из АХ в ВХ
pop AX ;достаем из стека числитель
cwd ;расширяем числитель до двойного слова DX:AX
idiv BX ;делим числитель на знаменатель в АХ-целая часть, в DX-остаток
push BX
push DX
push AX
mov AX, 135
imul x
mov BX, AX ;перемещаем DX:AX в CX:BX
mov CX, DX
pop AX ;достаем из стека целую часть дроби
cwd ;расширяем её до двойного слова DX:AX
add AX, BX ;складываем с ранее найденным произведением
adc DX, CX
;После вычислений в DX:AX-целая часть результата, в стеке DX-остаток от деления и ВХ-знаменатель дроби
;Конвертируем DX:AX в строку десятичных цифр
mov SI, DX ; сохраняем старшее слово в SI
mov BX, 10 ; делитель
mov CX, SP ; в СХ запоминаем вершину стека
big:
cmp DX, BX ; Войдёт ли результат деления в 16 бит?
jb smal ; да, DX < BX, так что результат уместится в AX!
xchg AX, SI ; старшее слово - в AX, сохраняем младшее слово в SI
xor DX, DX ; обнуляем DX
div BX ; делим старшее слово, остаток помещается в DX
xchg AX, SI ; меняем обратно
div BX ; делим младшее слово
push DX ; сохраняем остаток (0..9) в стек!
mov DX, SI ; prepare for next round
jmp big
smal: ; Remainder fits in lower 16 bits (AX)
div bx ; Divide, result stays in AX, remainder in DX
push dx ; Save remainder
xor dx,dx ; Prepare for next round
test ax,ax ; Any more digits?
jnz smal
; Все цифры собраны в стеке, теперь выводим их в строку:
mov DI, offset bufout
store:
pop ax
add al,'0'
mov [di],al
inc di
cmp cx,sp
jne store
mov al, '$'
mov [DI], al
mov AH, 09h
mov DX, offset bufout
int 21h
vixod:
mov AH, 4Ch ;номер функции 21-го прерывания*
int 21h ;передача управления в DOS
conv proc
mov DI, 0
lea BX, buf+1 ;В ВХ адрес второго элемента буфера
mov CX, [BX] ;в СХ кол-во введённых символов
xor CH, CH ;Обнуляем СН
mov SI, 1 ;в SI множитель
met:
push SI ;сохраняем SI (множитель) в стеке
mov SI, CX ;в SI помещаем номер текущего символа
mov AX, [BX+SI] ;в АХ помещаем текущий символ
xor AH, AH ;обнуляем АН
pop SI ;Извлекаем множитель (SI) из стека
sub AX, 30h ;получаем из символа (АХ) цифру
mul SI ;умножаем цифру (АХ) на множитель (SI)
add DI, AX ;складываем с результирующим числом
mov AX, SI ;помещаем множитель (SI) в АХ
mul m ;увеличиваем множитель (АХ) в 10 раз
mov SI, AX ;перемещаем множитель (АХ) назад в SI
loop met ;переходим к предыдущему символу
mov AH, 09h
lea DX, probel
int 21h
mov DX, DI
ret
conv endp
CodeSg ends; конец сегмента кода
end Bxod; конец программы с точкой входа[/code]