Программа, решающая уравнение в сборке


У меня проблема с моей простой программой в сборке. Я использую DOSbox и TASM . У меня проблема с программой. Типы операндов не совпадают в строке 76 78 80 . Это уже после умножения. Я попытался внести некоторые изменения, используя переменную difftrent size

; --------------------------------------------
; Equation=(a+c*b)/d-2*c,
; --------------------------------------------
.model small
.stack 100h
.data
        a       db 0                           
        b       db 0
        c       db 0
        d       db 0
        result1 db ?
        result2 db ?



        message1 db "Equation: (a+c*b)/d-2*c   a=$"
        message2 db "b=$"
        message3 db "c=$"
        message4 db "d=$"
        message5 db "Result=$"
.code

start:  mov ax,@data
                mov ds,ax                      

                mov ax, seg message1   ;get a and save to a variable
                mov ds,ax      
                mov dx,offset message1
                mov ah, 9h
                int 21h
                mov ah, 1h
                int 21h
                sub al,30h    ;converting to real number
                mov a,al

                mov ax, seg message2 ;get b and save to a variable
                mov ds,ax      
                mov dx,offset message2
                mov ah, 9h
                int 21h
                mov ah, 1h
                int 21h
                sub al,30h    ;converting to real number
                mov b,al


                mov ax, seg message3    ;get c and save to a variable
                mov ds,ax      
                mov dx,offset message3
                mov ah, 9h
                int 21h
                mov ah, 1h
                int 21h
                sub al,30h    ;converting to real number
                mov c,al


                mov ax, seg message4   ;get d and save to a variable
                mov ds,ax      
                mov dx,offset message4
                mov ah, 9h
                int 21h
                mov ah, 1h
                int 21h
                sub al,30h   ;converting to real number
                mov d,al


                mov al,b         ; (a+c*b) ------------------------error
                mul c                          
                add ax,a       ; ------------------------error

                push ax     ;save current ax

                mov ax,c     ;d-2*c------------------------error
                shl ax,2
                sub d,ax


                pop bx     ;get previous ax  to bx

                div bx     ; div ax:bx

                mov result1,al
                mov result2,ah

                add result1,30h   ;converting to string
                add result2,30h    ;converting to string

                mov al,result1
                mov bl,result2

                mov ax, seg message5
                mov ds,ax      
                mov dx,offset message5
                mov ah, 9h
                int 21h
                mov al,result1
                mov bl,result2
                mov dl, al
                mov ah , 2h
                int 21h
                mov dl, bl
                mov ah , 2h
                int 21h

                mov ax,4C00h           
                int 21h

end             start
1 5

1 ответ:

Ваша программа почти хороша, у вас есть только некоторые проблемы с размерами операндов, что нормально. Поэтому я взял ваш код и внес некоторые небольшие изменения, эти изменения прокомментированы и отмечены стрелками (

  • Исправлена проблема размера операнда. Я все еще использую DB, потому что заметил, что вы записываете числа как одиночные символы.
  • результат (d-2*c) сохраняется в BX. Это потому, что нам нужно разделить (a+c*b) / (d-2*c), и вы выскакивали (a+c*b) в BX, Итак, когда вы делаете div bx, вы делали (d-2*c) / (a+c*b).
  • разделил отображение на частное и остаток.
  • добавлены 13,10 разрывы строк в сообщениях.
  • исправлено shl ax,2 по shl ax,1. Один shl - x2, два shl - x2x2.
  • Остаток получается из dl, потому что когда div использует слово в качестве делителя, остаток остается в dx.

Вот ваш код с небольшими изменениями (протестирован на EMU8086):

; --------------------------------------------
; Equation=(a+c*b)/d-2*c,
; --------------------------------------------.model small
.stack 100h
.data
    a   db 0                
    b   db 0
    c   db 0
    d   db 0
    result1 db ?
    result2 db ?



    message1 db 13,10,"Equation: (a+c*b)/d-2*c",13,10,"a=$"
    message2 db 13,10,"b=$"         ;<================= 13,10 IS
    message3 db 13,10,"c=$"         ;<================= LINEBREAK.
    message4 db 13,10,"d=$"         ;<=================
    message5 db 13,10,"Quotient=$"  ;<=================
    message6 db 13,10,"Remainder=$" ;<=================
.code

start:  mov ax,@data
        mov ds,ax           



        mov ax, seg message1   ;get a and save to a variable
        mov ds,ax   
        mov dx,offset message1
        mov ah, 9h
        int 21h
        mov ah, 1h 
        int 21h
        sub al,30h    ;converting to real number
        mov a,al

        mov ax, seg message2 ;get b and save to a variable
        mov ds,ax   
        mov dx,offset message2
        mov ah, 9h
        int 21h
        mov ah, 1h
        int 21h
        sub al,30h    ;converting to real number
        mov b,al


        mov ax, seg message3    ;get c and save to a variable
        mov ds,ax   
        mov dx,offset message3
        mov ah, 9h
        int 21h
        mov ah, 1h 
        int 21h
        sub al,30h    ;converting to real number
        mov c,al


        mov ax, seg message4   ;get d and save to a variable
        mov ds,ax   
        mov dx,offset message4
        mov ah, 9h
        int 21h
        mov ah, 1h 
        int 21h
        sub al,30h   ;converting to real number
        mov d,al


        mov al,b          ; (a+c*b)
        mul c
        mov cl,A    ;<======== MOV A TO CX TO
        mov ch,0    ;<======== ADD IT TO AX.
        add ax,CX   ;<======== C*B + A.

       ;push ax     ;<======== NO LONGER NECESSARY BECAUSE
                    ;<======== IN NEXT BLOCK WE USE BX.

        mov bl,C    ;<======== MOV C TO BL AND CLEAR
        mov bh,0    ;<======== BH. NOW C IS IN BX.
        shl bx,1    ;<======== 2*c. ONE SHIFT IS x2, TWO SHIFTS ARE x2x2.
        sub d,bl          ;d - 2c
        mov bl,d    ;<======== MOV D TO BL AND CLEAR BH. NOW
        mov bh,0    ;<======== D IS IN BX. BX = (D-2C).

       ;pop ax      ;<======== NO LONGER NECESSARY. AX CONTAINS (A+C*B).

        mov dx,0    ;<======== CLEAR DX, BECAUSE DIVISOR IS A WORD.
                    ;<======== WHEN DIVISOR IS A WORD, DIV USES DX:AX. 
        div bx      ;<======== dx:ax / bx == DX:(A+C*B) / (D-2C). THIS
                    ;<======== DIVISION IS UNSIGNED, FOR SIGNED USE IDIV.

        mov result1,al ;<===== QUOTIENT.
        mov result2,dl ;<===== REMAINDER, BECAUSE DIVISOR IS WORD.

        add result1,30h   ;converting to string
        add result2,30h    ;converting to string

        mov al,result1
        mov bl,result2

      ;DISPLAY QUOTIENT  <=============
        mov ax, seg message5
        mov ds,ax   
        mov dx,offset message5
        mov ah, 9h
        int 21h
        mov al,result1
        mov dl, al
        mov ah , 2h
        int 21h       
      ;DISPLAY REMAINDER  <=============
        mov ax, seg message6
        mov ds,ax   
        mov dx,offset message6
        mov ah, 9h
        int 21h
        mov dl, bl
        mov ah , 2h
        int 21h

        mov ax,4C00h        
        int 21h

end     start

Далее идет ваше "делать" список:

    Измените размер операндов с DB на DW, чтобы ваша программа могла обрабатывать большие числа.
  • измените DIV на IDIV, потому что DIV не имеет знака, а IDIV подписан. IDIV позволит вам справиться с отрицательными результатами.
  • захват чисел с int=21h ah=0Ah в виде строк (не в виде одиночных символов). Позже вы преобразуете строки в числа. Следующие две ссылки приведут вас к процедурам преобразования строки в число:

Дата сборки x86 до Number-разбиение строки на более мелкие части

32 разрядный калькулятор в сборке 8086

Наконец, данные испытаний:

(a+c*b) / (d-2*c)

a=1
b=2
c=3
d=8

a+c*b = 1+3*2 = 7
d-2*c = 8-2*3 = 2

7 / 2 = quotient 3, remainder 1