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
ADD AX,RES2 ; ADD RES1 + RES2
;****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
1 Answer 1
I have some suggestions that may help you improve your code.
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.
Make comments more useful
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.
Think carefully about the problem
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.
-
\$\begingroup\$ Only wanted to fix a single typo! Had to include some extra text due to a 6-character submit threshold. \$\endgroup\$Sep Roland– Sep Roland2016年03月27日 21:52:44 +00:00Commented Mar 27, 2016 at 21:52
(Z-Z)+(X-Y)
why bother withZ
? It's always going to be simplyX-Y
, right? \$\endgroup\$