I have a problem with my simple program in assembly. I'm using DOSBox and TASM. The problem is that the operand types don't match in lines 76, 78, and 80. This is after multiplication. I tried to make some changes by using a different variable 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
Your program is almost good, you only have some issues with operand sizes, which is normal. So I took your code and made some little changes, those changes are commented and pointed by arrows (<========) and they are :
div bx
you were doing (d-2*c) / (a+c*b) .13,10
line breaks to messages.shl ax,2
by shl ax,1
. One shl
is x2, two shl
are x2x2.dl
because when div
uses a word as divisor, the remainder is left in dx
.Here is your code with the little changes (tested on 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
Next is your "to do" list:
Assembly x86 Date to Number - Breaking a string into smaller sections
32 bit Calculator in 8086 Assembly
Finally, the test data :
(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