The equation for solving programs in the assembly

I have a problem with my simple build program. I use DOSbox and TASM. I have problems with the program. Types of operands do not match on line 76 78 80. This is after multiplication. I tried to make some changes using the size of the difftrent variable

; -------------------------------------------- ; 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*ca=$" 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 
+5
source share
1 answer

Your program is almost good, you only have some problems with the size of the operands, which is normal. So I took your code and made some small changes, these changes are commented and indicated by arrows (<========), and they are:

  • Fixed problem with the size of the operand. I am still using the database because I noticed that you are fixing numbers as separate characters.
  • The result (d-2 * c) is stored in BX. This is because we need to split (a + c * b) / (d-2 * c) and you popped (a + c * b) into BX, so when you make div bx you did (d -2 * c) / (a ​​+ c * b).
  • Separate the display for private and rest.
  • Added 13,10 line breaks in messages.
  • Fixed shl ax,2 on shl ax,1 . One shl is x2, two shl is x2x2.
  • The rest is derived from dl , because when the div uses the word as a divisor, the remainder remains in dx .

Here is your code with slight modifications (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 do list:

  • Resize operands from DB to DW so that your program can handle large numbers.
  • Change the DIV to IDIV, because the DIV is unsigned, while the IDIV is signed. IDIV will allow you to handle negative results.
  • Capturing numbers with int = 21h ah = 0Ah as strings (not as separate characters). Later you convert strings to numbers. The following two links will lead you to string-to-number conversion procedures:

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

32-bit calculator in assembly 8086

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 
+3
source

All Articles