2015-06-04 2 views
5

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

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

Разместите код непосредственно здесь. – Carcigenicate

+1

.. и отметьте линии. Например, в пастах линии 76 и 80 пусты. Я как-то сомневаюсь, что ошибка там ... – Jester

+0

Каковы самые большие числа, которые ваша программа должна обрабатывать? –

ответ

3

Вашей программу почти хорошо, у вас есть только некоторые проблемы с размерами операндов, что является нормальным. Так что я взял код и сделал некоторые небольшие изменения, эти изменения комментируются и указали стрелки (< ========), и они:

  • Исправлена ​​проблема размера операнда. Я все еще использую БД, потому что заметил, что вы фиксируете числа в виде отдельных символов.
  • Результат (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 

Следующая ваша «делать» список:

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

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

32 bit Calculator in 8086 Assembly

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

(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

Спасибо. Теперь я сделаю это более полезным, как Ты сказал:> – Mack