2015-06-04 13 views
5

Ich habe ein Problem mit meinem einfachen Programm in der Montage. Ich benutze DOSbox und TASM. Ich habe ein Problem mit dem Programm. Operandentypen passen nicht zu Zeile 76 78 80. Dies ist nach der Multiplikation. Ich habe versucht, einige Änderungen vornehmen, indem Sie difftrent variabler GrößeProgramm lösen Gleichung in Assembly

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

Post Code direkt hier. – Carcigenicate

+1

.. und markieren Sie die Zeilen. In den Pasten sind beispielsweise die Zeilen 76 und 80 leer. Ich bezweifle irgendwie den Fehler dort ist ... – Jester

+0

Was sind die größten Zahlen, die Ihr Programm handhaben soll? –

Antwort

3

Ihr Programm ist fast gut, nur ein paar Probleme mit Operandengrößen haben, was normal ist. Also habe ich den Code nahm und einige kleine Änderungen, werden diese Änderungen kommentiert und deutete durch Pfeile (< ========) und sie sind:

  • Fest die Operandengröße Problem. Ich benutze immer noch DB, weil ich bemerkt habe, dass du die Zahlen als einzelne Zeichen festhältst.
  • Das Ergebnis von (d-2 * c) wird in BX gespeichert. Das liegt daran, dass wir (a + c * b)/(d-2 * c) teilen müssen und (a + c * b) in BX gepoppt haben. Wenn Sie also div bx tun, tun Sie (d-2 * c)/(a ​​+ c * b).
  • Die Anzeige für Quotient und Rest getrennt.
  • Hinzugefügt 13,10 Zeilenumbrüche zu Nachrichten.
  • Fixed shl ax,2 von shl ax,1. Eine shl ist x2, zwei shl sind x2x2.
  • Der Rest wird von dl erhalten, denn wenn div ein Wort als Divisor verwendet, bleibt der Rest in dx.

Hier ist der Code mit den kleinen Änderungen (auf EMU8086 getestet):

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

Weiter ist die Liste "to do":

  • Ändern der Größe der Operanden von DB DW, damit Ihr Programm mit größeren Zahlen umgehen kann.
  • DIV durch IDIV ändern, weil DIV vorzeichenlos ist, während IDIV signiert ist. IDIV lässt Sie negative Ergebnisse verarbeiten.
  • Erfassen Sie Zahlen mit int = 21h ah = 0Ah als Zeichenfolgen (nicht als einzelne Zeichen). Später konvertieren Sie die Strings in Zahlen. Die nächsten zwei Links führen Sie zu den Verfahren von String Zahl zu konvertieren:

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

32 bit Calculator in 8086 Assembly

schließlich die Testdaten:

(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

Danke. Jetzt werde ich es nützlicher machen, wie Du gesagt hast:> – Mack