@InfoLabs

Как поделить два числа ax, dx?

Доброй ночи. Ломаю голову неделю. Написал только 85% программы которая должна принимать два 16 битовых числа и рассчитывать по формуле A/B – 7*B

Проблема в том, что при попытке поделить:
A : 20 (mov ax, cx)
B : 2 (div bx)
= 6 (при любых вариантах)

А если писать так, например взять А, из введенного с клавиатуры, а второе число из регистра bl, то все хорошо делит
A : 20 (mov ax, cx)
mov bl, 2
B : 2 (div bl)
= 10

Как быть? Почему не делит?
data segment
    msgInputA db "Insert to value A: $"
    msgInputB db "Insert to value B: $"
    msgNumber db "Incorrect insert number$"
    buffer  db 6, 7 dup(?)
data ends
 
stk segment stack
    db 256 dup (?) 
stk ends
 
code segment
assume ds:data, cs:code, ss:stk
 
 
ShowHex proc
        push    ax
        push    cx
        push    dx
 
        ; Начинаем перевод числа AX в строку
        mov    cl,      ((16-1)/4)*4    ; 16-битный регистр, будем выводить по 4 бита (0..F)
        xchg   dx,      ax              ; Сохраняем число в DX
 
Repeat:
 
        mov    ax,      dx              ; Восстанавливаем число в AX
        shr    ax,      cl              ; Сдвигаем на CL бит вправо
        and    al,      0Fh             ; Получаем в AL цифру 0..15
        add    al,      '0'             ; Получаем в AL символ цифры
        cmp    al,      '9'             ; Проверяем цифру
        jbe    Digit09                ; Прыгаем, если это цифра 0..9
        add    al,      'A'-('9'+1)     ; Иначе (для A..F) корректируем ее
 
Digit09:
 
        int    29h                      ; Выводим символ в AL на экран
        sub    cl,      4               ; Уменьшаем CL на 4 для следующей цифры
        jnc    Repeat                 ; Если знаковый CL >= 0, то повторяем
 
        pop     dx
        pop     cx
        pop     ax
        ret
ShowHex endp
 
Insert proc
    ; Начало - Запись в буффер
    mov ah, 0ah ; ввод строки в буффер
    mov dx, offset buffer ; загрузим адрес буффера
    int 21h ; вызовем прерывание
    mov dl, 0ah ; ????
    mov ah, 02 ; загрузим перевод строки в регистр ah
    int 21h ; вызовем прерывание
    ; Конец - Запись в буффер
 
    ; Начало - Обработка информации из буфера
    mov si, offset buffer + 2 ; загрузим в регистровый указатель адрес буффера
    xor di, di  ; обнулим регистр
    cmp byte ptr [si], "-"    ; проверим на первый символ, если минус то:
    jnz negative
    inc di ; организуем смещение на один символ
    inc si    ; сместим указатель на еденицу
    ; Конец - Обработка информации из буфера
 
negative:
    xor ax, ax ; обнулим регистр
    mov bx, 10 ; основание cc
; Цикл прохода по каждому байту буффера, до нажатия кнопки Enter
loops:
    mov cl, [si] ; загрузим в счетчик символ из буффера
    cmp cl, 0dh  ; проверим является ли он последним, если да, то:
    je endin     ; перейдем, если ноль
 
    cmp cl, 30h  ; если меньше нуля, прыгнем на ошибку
    jl error     ; перейдем если не выше и не равно/ниже
    cmp cl, 39h  ; если больше девяти, прыгнем на ошибку
    ja error     ; перейдем если выше/не ниже и не равно
 
    sub cl, 30h  ; переконвертируем символ в число
    mul bx       ; умножим на десять
    add ax, cx   ; прибавим к остальным значениям в регистре
    
    inc si       ; пропустим следующий символ
    jmp loops    ; повторим до тех пор, пока не дойдем до нуля
error:
    mov dx, offset msgNumber ; вычисляем адрес и загружаем его в регистр
    mov ah, 09h   ; вывод строки
    int 21h      ; вызовем прерывание
    jmp exit
endin:
    cmp di, 1 ; проверим, было ли смещение (установлен ли флаг)
    jnz iend  ; если не ноль то завершаем
    neg ax    ; сделаем число негативным
iend:
    ret
Insert endp
 
; cx - A 
; bx - B
; A/B – 7*B.
Calc proc
    mov ax, cx
    div bx
    call ShowHex
    ret
Calc endp
 
main:    
    mov ax, data ; загрузим датасегмент в ax
    mov ds, ax   ; загрузим датасегмент из ax в ds
    xor ax, ax   ; обнулим 16-битовый регистр
 
    ; Начало - вывод сообщения
    mov dx, offset msgInputA ; вычисляем смещение (эффективный-адрес) и загружаем его в регистр
    mov ah, 9h ; вывод строки
    int 21h    ; прерывание DOS, получает управление, для обработки информации
    ; Конец - вывод сообщения
 
    ; Начало - Ввод А
    call Insert  ; запросим ввод символов
    mov cx, ax   ; загрузим результат ввода в регистр cx
    xor ax, ax   ; обнулим 16-битовый регистр
    ; Конец - Ввод А
 
    ; Начало - вывод сообщения
    mov dx, offset msgInputB ; вычисляем смещение (эффективный-адрес) и загружаем его в регистр
    mov ah, 9h ; вывод строки
    int 21h    ; прерывание DOS, получает управление, для обработки информации
    ; Конец - вывод сообщения
 
    ; Начало - Ввод B
    call Insert  ; запросим ввод символов
    mov bx, ax   ; загрузим результат ввода в регистр cx
    xor ax, ax   ; обнулим 16-битовый регистр
    ; Конец - Ввод B
 
    call Calc
    ; cx - A 
    ; bx - B
exit:
    mov ax, 4c00h
    int 21h
code ends
 
end main


MOVZX - не работает
  • Вопрос задан
  • 535 просмотров
Решения вопроса 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Про dx в делени вам уже сказали, я ещё добавлю то, что вы не очищаете ch перед loops, внутри цикла изменяете только cl, а к ax прибавляете cx. Попробуйте для контроля сразу распечатывать введённые числа.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы