I
I
InfoLabs2017-06-02 01:13:56
assembler
InfoLabs, 2017-06-02 01:13:56

How to divide two numbers ax, dx?

Goodnight. I've been scratching my head for a week. Wrote only 85% of the program that should take two 16 bit numbers and calculate according to the formula A / B - 7 * B
The problem is that when trying to divide:
A : 20 (mov ax, cx)
B : 2 (div bx)
= 6 (with any options)
And if you write like this, for example, take A from the input from the keyboard, and the second number from the bl register, then everything divides well
A : 20 (mov ax, cx)
mov bl, 2
B : 2 (div bl)
= 10
How to be? Why not share?

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 - not working

Answer the question

In order to leave comments, you need to log in

1 answer(s)
J
jcmvbkbc, 2017-06-02
@InfoLabs

You have already been told about dx in division, I will also add that you do not clear ch before loops, inside the loop you change only cl, and add cx to ax. Try to immediately print the entered numbers for control.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question