2015-06-04 11 views
5

Mam problem z moim prostym programem podczas montażu. Używam DOSbox i TASM. Mam problem z programem. Typy operacji nie pasują do linii 76 78 80. To jest po mnożeniu. Starałem się wprowadzić pewne zmiany za pomocą difftrent rozmiar zmiennejProgram do rozwiązywania równań w zespole

; -------------------------------------------- 
; 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 
+0

Wyślij swój kod tutaj bezpośrednio. – Carcigenicate

+1

.. i zaznacz linie. W wierszach pasty 76 i 80 są puste, na przykład. Jakoś wątpię, że błąd istnieje ... – Jester

+0

Jakie są największe liczby, które twój program ma obsłużyć? –

Odpowiedz

3

Program jest prawie dobrze, tylko masz jakieś problemy z rozmiarów operandów, co jest normalne. Więc wziąłem swój kod i kilka małych zmian, zmiany te są komentowane i wskazał strzałkami (< ========) i są to:

  • Naprawiono problem rozmiaru operandu. Nadal używam DB, ponieważ zauważyłem, że przechwytujesz liczby jako pojedyncze znaki.
  • Wynik (d-2 * c) jest zapisany w BX. Dzieje się tak dlatego, że musimy podzielić (a + c * b)/(d-2 * c), a ty pojawiłeś się (a + c * b) w BX, więc kiedy robisz div bx robisz (d-2 * c)/(a ​​+ c * b).
  • Oddzielono ekran dla ilorazu i reszty.
  • Dodano 13,10 linia zrywa komunikaty.
  • Naprawiono shl ax,2 przez shl ax,1. Jeden shl to x2, dwa shl to x2x2.
  • Pozostała część pochodzi z dl, ponieważ gdy div używa słowa jako dzielnika, pozostała część pozostaje w dx.

Oto kod z małymi zmianami (testowane na 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 

Następny to "zrobić" lista:

  • Zmień wielkość argumentów z DB DW, aby umożliwić programowi obsługę większych liczb.
  • Zmień DIV na IDIV, ponieważ DIV jest niepodpisany, a IDIV jest podpisany. IDIV pozwoli ci obsłużyć negatywne wyniki.
  • Przechwyć liczby z int = 21h ah = 0Ah jako ciągi znaków (nie jako pojedyncze znaki). Później konwertujesz łańcuchy na liczby. Kolejne dwa linki przeniesie Cię do procedur przekonwertować z ciągiem na numer:

Assembly x86 Date to Number - Breaking a string into smaller sections

32 bit Calculator in 8086 Assembly

Wreszcie, dane testowe:

(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 
+0

Dziękuję. Teraz sprawię, że będzie bardziej użyteczny, jak powiedziałeś:> – Mack