Simple calculation program in assembly MASM

I am a beginner in assembly. This program calculates:

(Z+Z)+(X-Y)

DATA_SEG    SEGMENT
X     DW 2
Y     DW 3
Z     DW 5
RES1  DW ?
RES2      DW ?
DATA_SEG        ENDS
CODE_SEG        SEGMENT

ASSUME CS:CODE_SEG, DS:DATA_SEG

;**********************************************
MAIN    PROC    FAR          ;MAIN PROGRAM STARTS HERE.

MOV     AX,DATA_SEG
MOV     DS,AX      ;INITIALIZING THE DS REGISTER.

; ***FIRST WE CALCULATE (Z+Z) AND SAVE IN RES1****
MOV     AX,Z     ;
add     AX,Z     ;  AX = Z+Z
MOV     RES1,AX  ;  HOLD TEMPORARILY THE RESULT OF (Z-Z) IN RES1

; ***SECOND WE CALCULATE  (Y-X) AND SAVE IN RES2***
MOV     AX,Y     ;  NOW STORE VAR Y IN AX REGISTER
SUB     AX,X     ;  PERFORM  AX = Y-X
MOV     RES2,AX  ;  HOLD TEMPORARILY THE RESULT OF (Y-X) IN RES2

; ***NOW ADD BOTH RES1 + RES2***

MOV     AX,RES1  ; STORE  RESULT OF (Z+Z) IN AX REGISTER

;****NOW FOR PRINTING WE MOVE THE VALUE IN DX REGISTER****

MOV     DX,AX    ; tO PRINT WE FIRST MOVE DATA IN DX REGISTER
ADD     DX,30H ;CONVERT TO ACSII CODE
MOV     AH,2
INT     21H
MOV     AH,04CH
INT     21H
MAIN    ENDP
CODE_SEG        ENDS
END     MAIN

• If you're calculating (Z-Z)+(X-Y) why bother with Z? It's always going to be simply X-Y, right? – Edward Mar 6 '16 at 19:44
• Ok you are right but this program as a practice not for real calculating. i want to know is this my solution is correct? – Syed Qasim Ahmed Mar 6 '16 at 19:45
• basically above program is my lab assignment for practice.How to use multiple vars in assembly. – Syed Qasim Ahmed Mar 6 '16 at 19:47

Fix formatting

There seem to be varying numbers of leading spaces on each line, impeding easy reading. Typically labels and directives start in column 1 and instructions start in column 9 (one tabstop) and are all aligned there. Many, including me, additionally align comments as well.

Comments like this are useful because they explain why we're doing something.

MOV     DX,AX    ; tO PRINT WE FIRST MOVE DATA IN DX REGISTER


Although it would be easier to read if it wasn't in ALL CAPS. Other comments are not useful because they explain something obvious from the instruction:

 MAIN    PROC    FAR          ;MAIN PROGRAM STARTS HERE.
;  other code
MOV     DS,AX      ;INITIALIZING THE DS REGISTER.


Eliminate "magic numbers"

There are a few numbers in the code, such as 30H and 2 that have a specific meaning in their particular context. By using named constants such as ASCII_ZERO or PRINT_CHAR, the program becomes easier to read and maintain.

As mentioned in a comment, if you're really calculating (Z-Z)+(X-Y) then you can simply ignore Z because (Z-Z) is always going to be zero. Next, the description says X-Y but the code says Y-X. It's usually essential to clearly understand the problem at hand before beginning to write the code.

Prefer registers to memory

Register use is typically much faster than memory use. For that reason, I'd recommend eliminating memory use that isn't needed. In particular, RES1 and RES2 could easily be eliminated by either chaining operations or storing temporary values in a register. By "chaining operations" I mean that (Z-Z)+(Y-X) is equivalent to Z-Z+Y-X (or simply Y-X) so one could simply evaluate the expression from left to right.

Use the appropriate OS service

The INT 21h, AH=02h is the "Write character to standard output" service, so it's only going to print a single character. That's fine if you're only ever going to have a single digit non-negative result, but that doesn't seem assured here. Better would be to create a function that converts the numeric result in AX to a string in memory and then use a function such as INT 21h, AH=40h, "Write to file or device" for output.

Set all appropriate registers for use by the OS services

The program exits with a call to the DOS "Terminate with error code" function (INT 21h, AH=4Ch) but fails to actually set the error code in AL.

• Only wanted to fix a single typo! Had to include some extra text due to a 6-character submit threshold. – Sep Roland Mar 27 '16 at 21:52