 | Code: ;
; ** 10/18/06 PROGRAM1 ASSEMBLER **
; AN ASSEMBLER PROGRAM THAT READS 8 NUMBERS BETWEEN 0-255
; AND CALCULATES THE MIN, MAX, AND AVG OF THOSE NUMBERS.
; IT WILL THEN OUPUT THE RESULTS TO THE SCREEN
;
BOOT EQU 0 ; address to get back to CP/M
READ EQU 1 ; keyboard read function number
PRINT EQU 2 ; console output function number
BDOS EQU 5 ; CP/M function call address
SPRINT EQU 9 ; string print function number
CR EQU 0Dh ; value of ASCII code of <Enter>
LF EQU 0Ah ; value of ASCII code of line feed
INPUTL EQU 8 ; input loop counter
;
;
ORG 100h ; standard origin for CP/M
LXI sp,sp0 ; initialize stack pointer
;
MVI C,SPRINT ; MESSAGE 1 WELCOME
LXI D,MESS1 ;
CALL BDOS ;
MVI L,INPUTL ;DELETE THE FOLLOWING 3 TEST LINES
MVI A,5
MVI B,6
SUB B
;
; **********************************************************************
; DATA IN
; **********************************************************************
;
AINPUT: MVI C,SPRINT ; MOVE PRINT # INTO C
LXI D,MESS2 ; MOVE MESSAGE 2 INTO D
CALL BDOS ; PRNT MESSAGE 2 TO SCRN
MVI C,READ ; MOVE READ # INTO C
CALL BDOS ; WAIT FOR USER TO ENTER #
SUI '0' ; CONVERT ASCII TO DECIMAL
PUSH PSW ; MOVE A INTO STACK
CALL BDOS ; WAIT FOR SECOND ENTRY
;
CPI CR ; CHECK FOR <ENTER>
JZ CRG ; IF ENTER GO TO CRG 1
;
JMP MULTIP ; IF NOT, GO TO MULTIPLYER
;
BINPUT: MVI C,READ
CALL BDOS ; THIS IS SEPERATE BECAUSE WHEN
CPI CR ; DONE MULTIPLYING, CRG2 MUST BE
JZ CRG ; CALLED TO PUSH A INTO STACK
JNZ MULTIP ;
;
; MULTIPLYER WILL SIMULATE X*10
;
MULTIP: SUI '0' ; CHANGE VALUE FROM ASCII TO DEC
MOV H,A ; SECURE INPUT DIGIT
POP B ; MOVE BASE 10 DIGIT INTO 10X MULTIPLYER
MOV A,B ; 1X
ADD A ; 2X
ADD A ; 4X
ADD A ; 8X
ADD B ; 9X
ADD B ; 10X
ADD H ; ADD DIGIT TO 10XA
PUSH PSW ; PUSH CURRENT VAL INTO STACK
JMP BINPUT ; JUMP CMD
;
CRG: DCR L ; DECREASE INPUTLOOP COUNTER
JNZ AINPUT ; IF INPUTLOOP COUNTER NOT 0, RPT
JZ MATH ; MATH WILL CALCULATE MIN, MAX, AND AVG
;
; **********************************************************************
; CALCULATIONS
; **********************************************************************
;
MATH: MVI H,0 ; MAKE H AND L A CLEAN SLATE
MVI L,0 ;
POP D ; OFFLOAD FIRST NUMBER INTO D-E
MOV E,D ; # IS CONTAINED IN D SO MOVE TO E
MVI D,0 ; SET D TO ZERO SO DAD IS UNAFFECTED
DAD D ; ADD D TO H-L PAIR
MOV A,E ; COPY E TO A
MOV B,A ; COPY E TO B SINCE IT IS 1ST NUMBER
MOV C,A ; COPY E TO C SINCE IT IS 1ST NUMBER
;
POP D ; OFFLOAD NEXT NUMBER
MOV E,D ; # IS CONTAINED IN D SO MOVE TO E
MVI D,0 ; SET D TO ZERO SO DAD IS UNAFFECTED
DAD D ; ADD D TO H-L PAIR
MOV A,E ; COPY E TO A
CMP B ; COMPARE A WITH B IF A IS SMALLER, REPLACE B WITH A
CC NEG ; NEG IS A-B REPLACE FN
CMP C ; COMPARE A WITH C IF A IS BIGGER, REPLACE C WITH A
CNC POS ; POS IS A-C REPLACE FN
;
POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
; POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
;
POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
;
POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
;
POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
;
POP D
MOV E,D
MVI D,0
DAD D
MOV A,E
CMP B
CC NEG
CMP C
CNC POS
;
MOV A,C ; STORING MIN AND MAX TO STACK
PUSH PSW
MOV A,B
PUSH PSW
;
MVI B,3 ; FINDING AVG
CALL DIVI ; DIVISION SUB ROUTINE
;
MOV A,L ; PRINT AVG
MVI C,SPRINT
LXI D,MESS6
CALL BDOS
;
MVI B,100 ; NUM DIG 3
CALL ASCII
MVI B,10 ; NUM DIG 2
CALL ASCII
ADI '0' ; NUM DIG 1
MOV E,A
MVI C,2
CALL BDOS
;
POP B ; PRINT MIN
MOV A,B
MVI C,SPRINT
LXI D,MESS4
CALL BDOS
MVI B,100
CALL ASCII
MVI B,10
CALL ASCII
ADI '0'
MOV E,A
MVI C,2
CALL BDOS
;
POP B ; PRINT MAX
MOV A,B
MVI C,SPRINT
LXI D,MESS5
CALL BDOS
;
MVI B,100
CALL ASCII
MVI B,10
CALL ASCII
ADI '0'
MOV E,A
MVI C,2
CALL BDOS
;
JMP FINISH
;
; **********************************************************************
; OUTPUT DATA
; **********************************************************************
;
FINISH: MVI C,SPRINT ; print a log out message
LXI D,MESS7 ;
CALL BDOS ;
JMP BOOT ; and get back to the operating system
;
; **********************************************************************
; SUB ROUTINES
; **********************************************************************
;
NEG: MOV B,A
RET
;
POS: MOV C,A
RET
;
;
DIVI: MOV A,H
RAR
MOV H,A
MOV A,L
RAR
MOV L,A
DCR B
JNZ DIVI
RET
;
ASCII: MVI E,'0'
RPT: SUB B
JC CNTR
INR E
JMP RPT
CNTR: ADD B
MVI C,PRINT
CALL BDOS
MOV E,A
RET
;
; **********************************************************************
; MESSAGES AND STACK
; **********************************************************************
;
mess1: db ' Welcome to #Cruncher 1.0 '
db lf,cr, 'The easy way to calculate min max & avg of 8 #s'
db lf,cr, ' '
db lf,cr, 'Created By: comp-e (c) October 2006 '
db lf,cr, '$'
mess2: db lf,cr, 'Please enter a # from 0-255. $'
mess4: db lf,cr, 'MIN = $'
mess5: db lf,cr, 'MAX = $'
mess6: db lf,cr, 'AVG = $'
mess7: db lf,cr, 'Come Back Again!'
db lf,cr, ' '
db lf,cr, '$'
;
ds 18 ; 18 bytes reserved for stack
sp0 equ $ ; sp start
;
end ; terminate prgm
|  |