My Library
A.N Edition
This is my own library. I found out in MASM it is very inconvenient as we don't have a standard built-in
library like c, c++. So I decide to write my own version. Although it may not be as efficient as others do,
at least they are my own version. This is an accumulative version that I continually add new codes.
B.Idea of program
1。 Basic idea:
Try to write as many as possible c,c++ similar simple functions in MASM.
2。 Major function
A. INPUTNUMBER
;INPUT: NONE ;OUTPUT: BY AX, AND DX A VALID INTEGER, DX WILL BE INITIALIZE TO 0, BEFORE KEYIN BY USER
It is very easy to use "cin" in c, but behind scene, there is a lot job is going to be done for a single number input.
This version is incomplete, as I have not solved big number input, say number bigger than 65535. I originally thought to use
DX to represent the big part. But it seems there is some problem.
B. GCD, LCM
These two functions are just for fun! I want to practice Euclide Algorithm. Do people ever want to find out "Greatest Common
Divisor" or "Least Common Multiplication"? LCM use GCD to calculate.
C. DISPLAYINTEGER
This is my favorite. As I spent so much time to try to find out dividing mechanism. DX must be 0, otherwise there will be overflow.
TITLE MYLIB
COMMENT # THIS IS MY LIBRARY ALTHOUGH MANY FUNCTIONS ARE JUST QUITE SAME AS
# EXAMPLE GIVEN IN GRAPHIC, BUT I PREFER TO WRITE IT AGAIN BY MYSELF
DIM EQU 15
CELLSIZE EQU 8;
VERTICAL_BAR EQU 0BAH
HORIZONTAL_BAR EQU 0CDH
UPPER_LEFT EQU 0C9H
UPPER_RIGHT EQU 0BBH
MODULUS EQU 00FFFH
MULTIPLIER EQU 16807
SCALOR EQU 5
SHIFTOR EQU 12
CHARSCOPE EQU 127
.DOSSEG
.MODEL SMALL
.DATA
MSGOVERFLOW DB "OVERFLOW!", "$"
MSGINVALIDNUMBER DB "INVALID NUMBER!","$"
MSGNEGATIVENUMBER DB "NEGATIVE NUMBER!", "$"
MSGDECRYPTIONFAILED DB "DECRYPTION FAILED", "$"
.CODE
PUBLIC ENTERGRAPHIC
PUBLIC ENTERTEXT
PUBLIC WAITRETURN
PUBLIC DRAWBOX
PUBLIC DRAWVERLINE
PUBLIC DRAWHORLINE
PUBLIC DRAWGRID
PUBLIC FILLGRID
PUBLIC DRAWBOARD
PUBLIC DISPLAYINTEGER
PUBLIC GCD
PUBLIC LCM
PUBLIC RETURN
PUBLIC SPACE
PUBLIC INPUTNUMBER
PUBLIC DRAWHORIZONTAL
PUBLIC DRAWVERTICAL
PUBLIC SHOWCHAR
PUBLIC CLEARSCREEN
PUBLIC STRCPY
PUBLIC STRCMP
PUBLIC DISPLAYINTEGERB
PUBLIC DISPLAYINTEGERH
PUBLIC WAITRIGHTBTN
PUBLIC WAITLEFTBTN
PUBLIC MOUSERELEASE
PUBLIC MOUSESHOW
PUBLIC MOUSEHIDE
PUBLIC MOUSEINIT
PUBLIC MOUSEPOS
PUBLIC GETCELLINDEX
PUBLIC MOUSECLICK
PUBLIC FACTORIAL
PUBLIC INPUTNSTR
PUBLIC SUBSTRING
PUBLIC DISPLAYSTR
PUBLIC RAND
PUBLIC ENCRYPTION
PUBLIC DECRYPTION
;FUNCTION: DECRIPT A STRING PASSED BY STACK WITH PRE-DEFINED SCALOR AND SHIFTOR
;INPUT: BY STACK THE STRING TO BE DECRIPTED
;OUTPUT: NONE
DECRYPTION PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH DI
PUSH SI
MOV BX, [BP+4]; BX IS POINTING TO STRING
L77:
XOR AX, AX
MOV AL, [BX];
CMP AL, "$"
JE L70; THE END OF STRING
;SUB AL, SHIFTOR
;XOR DX, DX; PREPARE CALULATE MOD
MOV SI, SCALOR; SI IS SCALOR
;MOV CX, CHARSCOPE
;DIV CX; GET MOD DIV BY CHARSCOPE
;MOV DI, DX; DI KEEP THE OLD MOD
MOV DI, AX;
MOV CX, SCALOR;
DEC CX; LESS 1; CX IS COUNTER AND SCALOR
L76:
MOV AX, CHARSCOPE
MUL CX
ADD AX, DI; SUB OLD MOD
SUB AX, SHIFTOR
XOR DX, DX
DIV SI; DIV SCALOR TO SEE IF REMAINDER IS 0
CMP DX, 0
JE L75; SUCCEED AND ...
DEC CX
CMP CX, 0
JGE L76
;THIS SHOULD NOT HAPPEN!!!
MOV DX, OFFSET MSGDECRYPTIONFAILED
CALL SHOWMSG
INC BX
JMP L77
L75:
MOV [BX], AL; AL THE QUOTIENT
INC BX; NEXT
JMP L77
L70:
POP SI
POP DI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
DECRYPTION ENDP
;ENCRIPT A STRING PASSED BY STACK WITH PRE-DEFINED SCALOR AND SHIFTOR
;OUTPUT: NONE
;INPUT: BY STACK THE STRING ENDED WITH "$"
ENCRYPTION PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX, [BP+4]; BX IS POINTING THE STRING
XOR DX, DX
L79:
XOR CX, CX
MOV CL, [BX]
CMP CL, "$"
JE L78; DON'T CHANGE "$"
MOV AX, SCALOR
MUL CX
ADD AX, SHIFTOR
MOV CX, CHARSCOPE
XOR DX, DX
DIV CX
MOV [BX], DL
INC BX
JMP L79
L78:
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
ENCRYPTION ENDP
;FUNCTION: GENERATING RANDOM NUMBERS AND THE OUTPUT CONTINUALLY
;INPUT: AX THE SEED, IF FIRST TIME THE STARTING SEED
;OUTPUT: AX THE MOD
RAND PROC NEAR
PUSH BX
PUSH DX
XOR DX, DX
MOV BX, MULTIPLIER
MUL BX
MOV BX, MODULUS
DIV BX
MOV AX, DX
POP DX
POP BX
RET
RAND ENDP
;FUNCTION: THIS IS A JOKE! I USE 09H INT TO DISPLAY
;INPUT: BY STACK, THE STRING
;OUTPUT: NONE
DISPLAYSTR PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH DX
MOV DX, [BP+4]
MOV AH, 09H
INT 21H
POP DX
POP AX
POP BP
RET 2
DISPLAYSTR ENDP
;FUNCTION: INPUT MAX N NUMBER OF CHAR FROM KEYBOARD AND ADD "$" AT END
;INPUT: CHAR BUFFER, N NUMBER ALL FROM STACK
;OUTPUT: NONE
INPUTNSTR PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
MOV BX, [BP+6]; THE ARRAY
MOV CX, [BP+4]; THE COUNTER
DEC CX; AS WE CAN ONLY ALLOW MAX N-1 CHAR
L63:
MOV AH, 01H
INT 21H
CMP AL, 0DH; THE RETURN
JE L62; THE END OF INPUT
MOV [BX], AL
INC BX
LOOP L63
L62:
MOV BYTE PTR [BX], "$"
POP CX
POP BX
POP AX
POP BP
RET 4
INPUTNSTR ENDP
;FUNCTION: SEARCH A SUB STRING IN A TARGET STRING WHICH ARE PASSED BY STACK
;INPUT: BY STACK, TARGET STR, SUB STR
;OUTPUT: AX, 0 FOR NOT MATCH, 1 FOR MATCH
SUBSTRING PROC NEAR
PUSH BP
MOV BP, SP
PUSH DI
PUSH SI
MOV DI, [BP+6]; THE TARGET STR
MOV SI, [BP+4]; THE SUB STR
L66:
CMP BYTE PTR [DI], "$"
JE L65; THE END OF COMP
CMP BYTE PTR [SI], "$"; FOUND!
JMP FOUNDSUBSTR; RIGHT?
MOV BYTE PTR AL, [DI]
CMP BYTE PTR [SI], AL
JNE L64; NOT SAME, SO ADVANCE
INC SI
INC DI
JMP L66
L64:
MOV SI, [BP+4]; SUBSTRING STARTOVER
INC DI; TARGET ADVANCE
JMP L66
L65:
CMP BYTE PTR [SI], "$"
JE FOUNDSUBSTR
JMP NOTFOUNDSUBSTR
FOUNDSUBSTR:
MOV AX, 1
JMP ENDSEARCHING
NOTFOUNDSUBSTR:
MOV AX, 0;
ENDSEARCHING:
POP SI
POP DI
POP BP
RET 4
SUBSTRING ENDP
;FUNCTION: RETURN VALUE OF FACTORIAL INPUT FROM STACK
;INPUT: BY STACK, AN POSITIVE INTEGER
;OUTPUT: BY STACK THE VALUE OF FACTORIAL
FACTORIAL PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH DX
MOV AX, [BP+4]
CMP AX, 00H;
JL MINUSVALUE
CMP AX, 00H
JE L69
MOV BX, AX
DEC BX
PUSH BX
CALL FACTORIAL
POP BX
XOR DX, DX; MAKE SURE DX IS 0
MUL BX
MOV [BP+4], AX
JMP FACTORIAL_
MINUSVALUE:
MOV AH, 09H
MOV DX, OFFSET MSGNEGATIVENUMBER
INT 21H
JMP FACTORIAL_
L69:
MOV AX, 01H
MOV [BP+4], AX
FACTORIAL_:
POP DX
POP CX
POP AX
POP BP
RET
FACTORIAL ENDP
;FUNCTION: INTERNAL METHOD CALC ARRAY INDEX, BY GIVING OFFSET OF X, Y
;INPUT: OFFSET OF X,OFFSET OF Y, DIM OF GRID, CELLSIZE
;OUTPUT: ROW, COL BY STACK, ROW =-1 INDICATE OUTSIDE, OR ON GRIDLINE!!!
CALCINDEX PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
;FIRST SEE IF OFFSET IS MINUS
MOV BX, [BP+10]; BX IS X OFFSET
CMP BX, 00H
JL OUTBOUNDS; IF OFFSET IS MINUS, OUTSIDE
MOV BX, [BP+8]; BX IS Y OFFSET
CMP BX, 00H
JL OUTBOUNDS; IF OFFSET IS MINUS, OUTSIDE
;FIRST CALC BOUNDS TO SEE IF IT IS OUTSIDE WHICH IS EASIEST
MOV AX, [BP+6]; THE DIM
MOV CX, [BP+4]; THE CELL SIZE
;A TEST
;ADD CX, 2; AS THERE ARE 2 LINES
;A TEST
INC CX; AS THERE ARE ONE LINE TO BE ADDED
MUL CX;
;NOT NECESSARY
;INC AX; AS THERE IS ONE LINE AT BOUND, AX IS BOUNDSIZE
;NOW COMPARE BOUNDS WITH X
MOV BX, [BP+10]; BX IS X OFFSET
CMP AX, BX
JL OUTBOUNDS
;NOW COMPARE BOUNDS WITH Y
MOV BX, [BP+8]; BX IS Y OFFSET
CMP AX, BX
JL OUTBOUNDS
;NOW FIRST CALC Y, OR ROW INDEX
MOV AX, [BP+8]; Y OFFSET
XOR DX, DX; MAKE SURE DX IS 0 BEFORE DIVIDING!!!
DIV CX;
CMP DX, 00H; TO SEE IF IT IS ON GRID LINE!
JE OUTBOUNDS; ON GRIDLINE IS SAME EFFECT AS OUTSIDE
MOV SI, AX; THE QUOTIENT IS INDEX OF ROW; BUT UNLESS COL IS NOT ON GRIDLINE
MOV AX, [BP+10]; THE OFFSET X
XOR DX, DX; CLEAR DX BEFORE DIV
DIV CX
CMP DX, 00H
JE OUTBOUNDS
MOV [BP+10], SI; THE ROW INDEX
MOV [BP+8], AX; THE COL INDEX
JMP CALCINDEX_
OUTBOUNDS:
MOV AX, -1;
MOV [BP+10], AX
CALCINDEX_:
POP SI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 4
CALCINDEX ENDP
;FUNCTION: GET ROW,COL OF A GRID BY GIVING LEFTTOP COOR, X POS,Y POS, CELLSIZE,
; DIMENSION OF GRID
;INPUT: ORIGIN X,ORIGIN Y, MOUSEPOS X, MOUSEPOS Y, DIM OF GRID, CELLSIZE
;OUTPUT: BX=ROW, SI=COL; IF OUTSIDE, BX=-1
GETCELLINDEX PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH CX
PUSH DX
MOV AX, [BP+14]; X ORIGIN
MOV CX, [BP+10]; MOUSE POS X
SUB CX, AX; XPOS - X ORIGIN
PUSH CX; PASS OFFSET X
MOV AX, [BP+12]; THE Y ORIGIN
MOV DX, [BP+8]; MOUSE POS Y
SUB DX, AX; YPOS - Y ORIGIN
PUSH DX; PASS OFFSET Y
MOV AX, [BP+6]; DIM
PUSH AX
MOV AX, [BP+4]; CELLSIZE
PUSH AX
CALL CALCINDEX
POP SI; COL IS FIRST
POP BX; ROW IS SECOND??
POP DX
POP CX
POP AX
POP BP
RET 12
GETCELLINDEX ENDP
;FUNCTION: TO GET COORDINATE OF MOUSE
;OUTPUT: CX=X, DX=Y
;INPUT: NONE
MOUSEPOS PROC NEAR
PUSH AX
PUSH BX
MOV AX, 03H
INT 33H
POP BX
POP AX
RET
MOUSEPOS ENDP
;FUNCTION: RETURN UNTIL RIGHT MOUSE BUTTON IS CLICKED
;INPUT: NONE
;OUTPUT: NONE
WAITRIGHTBTN PROC NEAR
PUSH BX
PUSH CX
PUSH DX
WAITCLICK3:
CALL MOUSECLICK
CMP BX, 02H
JNE WAITCLICK3
POP DX
POP CX
POP BX
RET
WAITRIGHTBTN ENDP
;FUNCTION: RETURN UNTIL LEFT MOUSE BUTTON IS CLICKED
;INPUT: NONE
;OUTPUT: NONE
WAITLEFTBTN PROC NEAR
PUSH BX
PUSH CX
PUSH DX
WAITCLICK4:
CALL MOUSECLICK
CMP BX, 01H
JNE WAITCLICK4
POP DX
POP CX
POP BX
RET
WAITLEFTBTN ENDP
;FUNCTION: RETURN UNTIL MOUSE BUTTON IS CLICKED
;INPUT: NONE
;OUTPUT: BX IS STATE OF BUTTON, CX=X, DX=Y
MOUSECLICK PROC NEAR
PUSH AX
MOV AX, 03H
WAITCLICK1:
INT 33H
CMP BX, 00H
JE WAITCLICK1
POP AX
RET
MOUSECLICK ENDP
;FUNCTION: RETURN UNTIL MOUSE BUTTON IS RELEASED
;INPUT: NONE
;OUTPUT: BX IS STATE OF BUTTON, CX=X, DX=Y
MOUSERELEASE PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, 03H
WAITCLICK2:
INT 33H
CMP BX, 00H
JNE WAITCLICK2
POP DX
POP CX
POP BX
POP AX
RET
MOUSERELEASE ENDP
;FUNCTION: SHOW MOUSE
;INPUT: NONE
;OUTPUT: NONE
MOUSESHOW PROC NEAR
PUSH AX
MOV AX, 01H
INT 33H
POP AX
RET
MOUSESHOW ENDP
;FUNCTION: HIDE MOUSE
;INPUT: NONE
;OUTPUT: NONE
MOUSEHIDE PROC NEAR
PUSH AX
MOV AX, 02H
INT 33H
POP AX
RET
MOUSEHIDE ENDP
;FUNCTION: INITIALIZE MOUSE DRIVER
;INPUT: NONE
;OUTPUT: NONE
MOUSEINIT PROC NEAR
PUSH AX
MOV AX, 00H
INT 33H
CMP AX, -1; -1 MEANS OK
JE MOUSEINIT_
PUSH DS
PUSH DX
MOV AX, CS
MOV DS, AX
MOV AH, 09H
MOV DX, OFFSET MOUSEERRORMSG
INT 21H
POP DX
POP DS
MOV AX, 04C01H
INT 21H
MOUSEINIT_:
POP AX
RET
MOUSEERRORMSG DB "!!!!!!!MOUSE DRIVER NOT INITIALIZED!"
DB "TERMINATING PROGRAM!!! 0DH, 0AH", "$"
MOUSEINIT ENDP
;FUNCTION: DISPLAY A INTEGER IN BINARY FORM
;INPUT: BY STACK A INTEGER
;OUTPUT: NONE
DISPLAYINTEGERB PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
XOR BX, BX
MOV BX, [BP+4]; THE NUMBER IN BX
MOV CX, 4
MOV AH, 02H
L20:
PUSH CX
MOV CX, 4; SPLIT INTO 4X4 TO INSERT SPACE IN BETWEEN
L4BITS:
MOV DL, 00H
RCL BX, 1
ADC DL, 30H
INT 21H
LOOP L4BITS
POP CX
CALL SPACE
LOOP L20
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
DISPLAYINTEGERB ENDP
;FUNCTION: DISPLAY A INTEGER IN HEXIDECMAL
;INPUT: BY STACK A INTEGER
;OUTPUT: NONE
DISPLAYINTEGERH PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV BX, [BP+4];
MOV CX, 4;
L129:
PUSH CX; CANNOT ROL BX, 4???!!!
MOV CX, 4
L128:
ROL BX, 1;
LOOP L128
POP CX; RESTORE CX
MOV AX, BX
MOV DX, 0FH; DX AS MASK
AND AX, DX; AX GET THE HEX
MOV DL, 00H
CMP AX, 9
JS ADD30H
MOV DL, 17
ADD30H:
ADD DL, 30H
ADD DL, AL; ADD THE HEX TO
MOV AH, 02H
INT 21H
LOOP L129
MOV DL, 'H'
INT 21H
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2
DISPLAYINTEGERH ENDP
;FUNCTION: CMP STRING BYTE BY BYTE
;INPUT: BY STACK THE TWO STRING ADD
;OUTPUT: AX, 0=EQUAL, 1=FIRST BIGGER, -1=SECOND BIGGER
STRCMP PROC NEAR
PUSH BP
MOV BP, SP
PUSH SI
PUSH DI
PUSH ES
MOV DI, [BP+6]; THE FIRST
MOV SI, [BP+4]; THE SECOND
MOV AX, DS
MOV ES, AX
BEGINCMP:
;CMP BYTE [DI], [SI]
JG FIRSTBIG
;JL SECONDBIG
;JMP ENDCMP
FIRSTBIG:
MOV AX, 1
JMP ENDCMP
SECONDBIG:
MOV AX, -1
JMP ENDCMP
ENDCMP:
MOV AX, 0
POP ES
POP DI
POP SI
POP BP
RET
STRCMP ENDP
;FUNCTION: COPY STRING TERMINATED WITH "$"
;OUTPUT: NONE
;INPUT:BY STACK, DEST ADD, SOURCE ADD
STRCPY PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH SI
PUSH DI
PUSH ES
MOV SI, [BP+4]; SOURCE
MOV DI, [BP+6]; DEST
MOV AX, DS
MOV ES, AX
REP MOVSB; MOV BYTE BY BYTE UNTIL "$"
POP ES
POP DI
POP SI
POP AX
POP BP
RET 4
STRCPY ENDP
;FUNCTION: CLEAR SCREEN BY WRITE 0 TO VIDEO MEMORY
;OUTPUT: NONE
;INPUT: NONE
CLEARSCREEN PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH ES
MOV CX, 64000
XOR BX, BX
MOV AX, 0A000H
MOV ES, AX
XOR AL, AL
L59:
MOV ES:[BX], AL
INC BX
LOOP L59
POP ES
POP CX
POP BX
POP AX
RET
CLEARSCREEN ENDP
;DRAW VERTICAL BAR
;INPUT:NONE
;OUTPUT: NONE
DRAWVERTICAL PROC NEAR
PUSH DX
MOV DL, VERTICAL_BAR
CALL SHOWCHAR
POP DX
RET
DRAWVERTICAL ENDP
;DRAW HORIZONTAL BAR
;INPUT:NONE
;OUTPUT: NONE
DRAWHORIZONTAL PROC NEAR
PUSH DX
MOV DL, HORIZONTAL_BAR
CALL SHOWCHAR
POP DX
RET
DRAWHORIZONTAL ENDP
;FUNCTION: SHOW A CHAR
;INPUT: ONE CHAR IN DL
;OUTPUT: NONE
SHOWCHAR PROC NEAR
PUSH AX
MOV AH, 02H
INT 21H
POP AX
RET
SHOWCHAR ENDP
;FUNCTION: GET A KEYED IN VALID INTEGER FROM USER
;INPUT: NONE
;OUTPUT: BY AX, AND DX A VALID INTEGER, DX WILL BE INITIALIZE TO 0,
;BEFORE KEYIN BY USER
INPUTNUMBER PROC NEAR
PUSH BX
PUSH CX
MOV AH, 00H
MOV BX, 00H
MOV DX, 00H
MOV CX, 00H; CX STORE THE OLD NUMBER
NOMORE:
MOV AH, 01H
INT 21H
MOV BL, AL; STORE NEW NUMBER
MOV AX, CX
CMP BL, 0DH
JE ENDINPUTLOOP
CMP BL, 30H
JL NOTINTEGER
CMP BL, 39H
JG NOTINTEGER
SUB BL, 30H
MOV CX, 10
MUL CX; MUL OLD NUMBER BY 10
CMP DX, 00H
JNE L19
ADD AX, BX; ADD NEW NUMBER
JO L19
MOV CX, AX; AND DX REMAINS UNCHANGED IF THERE IS ANY NUMBER
JMP NOMORE
L19:
MOV DX, OFFSET MSGOVERFLOW
CALL SHOWMSG
JMP ENDALL
NOTINTEGER:
MOV AH, 09H
MOV DX, OFFSET MSGINVALIDNUMBER
INT 21H
JMP ENDALL
ENDINPUTLOOP:
MOV AX, CX
ENDALL:
POP CX
POP BX
RET
INPUTNUMBER ENDP
;FUNCTION: SHOW A STRING MESSAGE
;OUTPUT: NONE
;INPUT: DX CONTAIN THE OFFSET OF MSG
SHOWMSG PROC NEAR
PUSH AX
MOV AH, 09H
INT 21H
CALL RETURN;
POP AX
RET
SHOWMSG ENDP
SPACE PROC NEAR
PUSH AX
PUSH DX
MOV AH, 02
MOV DL, ' '
INT 21H
POP DX
POP AX
RET
SPACE ENDP
;FUNCTION: RETURN TO NEW LINE;(VERY FUNNY?)
;INPUT: NONE
;OUTPUT: NONE
RETURN PROC NEAR
PUSH AX
PUSH DX
MOV AH, 02H
MOV DL, 0DH
INT 21H
MOV DL, 0AH
INT 21H
POP DX
POP AX
RET
RETURN ENDP
;FUNCTION: FIND THE LEAST COMMON MULTIPLICATION
;INPUT: BY STACK, TWO NUMBERS
;OUTPUT; BY STACK, THE LEAST COMMON MULTIPLICATION
LCM PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH DX
MOV AX, [BP+6]; THE FIRST NUMBER
MOV DX, [BP+4]; THE SECONDE NUMBER
PUSH AX
PUSH DX
CALL GCD; TO FIND THEIR GCD
MUL DX; FIND THE MULTIPLICATION OF TWO NUMBER
POP BX; BX IS THE GCD
DIV BX; THIS GET THE LCM
MOV [BP+6], AX
POP DX
POP BX
POP AX
POP BP
RET 2
LCM ENDP
;FUNCTION: DISPLAY A INTEGER IN ASCII
;INPUT: BY STACK A INTEGER
;OUTPUT: NONE
DISPLAYINTEGER PROC
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, [BP+4]; THE INTEGER
MOV BX, 10; THE DIVISOR
MOV CX, 00H
DIVIDINGLOOP:
MOV DX, 00H
DIV BX
PUSH DX
INC CX;
CMP AX, 00H
JNE DIVIDINGLOOP
MOV AH, 02H
DISPLAYLOOP:
POP DX;
ADD DX, 30H
INT 21H
LOOP DISPLAYLOOP;
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2;
DISPLAYINTEGER ENDP
;GREATEST COMMON DIVISOR
;INPUT: BY STACK, TWO INTEGER
;OUTPUT: BY STACK GCD
GCD PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, [BP+6]; THE DIVIDANT
MOV BX, [BP+4]; THE DIVISOR
GCDLOOP:
MOV DX, 00H; IMPORTANT
DIV BX
CMP DX, 00H
JE OUTGCDLOOP
MOV AX, BX; DIVISOR BECOME DIVIDANT
MOV BX, DX; THE REMAINDER BECOME DIVISOR
JMP GCDLOOP
OUTGCDLOOP:
MOV [BP+6], BX
POP DX
POP CX
POP BX
POP AX
POP BP
RET 2;
GCD ENDP
; INPUT: NONE
; OUTPUT: NONE
; FUNCTION: CHANGE TO GRAPHIC MODE
ENTERGRAPHIC PROC
PUSH AX
MOV AX, 0A000H
MOV ES, AX
MOV AH, 00H
MOV AL, 13H
INT 10H
;CALL REFRESH
POP AX
RET
ENTERGRAPHIC ENDP
;INPUT: NONE
DRAWBOARD PROC
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV AX, 20
PUSH AX; X
PUSH AX; Y
MOV AX, 8
PUSH AX; 8 ROW
PUSH AX; 8 COL
MOV AX, 20; WIDTH
PUSH AX
MOV AX, 11
PUSH AX; COLOR
CALL INTERNALDRAWGRID
MOV CX, 0
LOCAL10:
CMP CX, 8
JE OUTLOCAL10
MOV BX, CX
PUSH CX; SAVE ROW NUMBER
MOV CX, 0; START THE NEW COL
LOCAL11:
CMP CX, 8
JE ENDOUTER
; THE PARAM ARE SAME
MOV AX, 20
PUSH AX; X
PUSH AX; Y
PUSH BX; ROW
PUSH CX; COL
MOV AX, 20; WIDTH
PUSH AX
;THE FOLLOWING IS COLOR BY ROW AND COL
MOV AX, CX;
AND AX, 1
CMP AX, 0
JE COLEVEN
;COL IS ODD
MOV AX, BX
AND AX, 1
CMP AX, 0
JE BLACKDRAW; ODD+EVEN=BLACK
JMP WHITEDRAW; ODD +ODD = WHITE
COLEVEN:
MOV AX, BX
AND AX, 1
CMP AX, 0
JE WHITEDRAW ; EVEN+EVEN = WHITE
JMP BLACKDRAW ; EVEN +ODD = BLACK
WHITEDRAW:
MOV AX, 15; WHITE
JMP NEXTDRAW
BLACKDRAW:
MOV AX, 8; BLACK
NEXTDRAW:
PUSH AX
CALL FILLGRID
ENDINNER:
INC CX
JMP LOCAL11
ENDOUTER:
POP CX
INC CX
JMP LOCAL10
OUTLOCAL10:
POP DX
POP CX
POP BX
POP AX
RET
DRAWBOARD ENDP
;INPUT X, Y, ROW, COL, WIDTH, COLOR
INTERNALDRAWGRID PROC
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH SI
PUSH DI
MOV AX, [BP+12]; Y
MOV BX, 320
MUL BX
ADD AX, [BP+14]; +X
MOV BX, AX; BX HOLDS THE OFFSET
MOV SI, [BP+10]; THE ROW
MOV DI, [BP+8]; THE COL
MOV AX, [BP+6]; THE GRIDLENGTH
MUL SI; CAL ROW LENGTH
ADD SI, AX; PLUS THE ROW LINE WIDTH
INC SI; ONE MORE LINE FOR ROW, AS 15 ROW HAS 16 LINE, SI IS THE HEIGHT
MOV AX, [BP+6]; GRIDLENGTH TO PREPARE TO CAL COL LENGTH
MUL DI; CAL COL LEN
ADD DI, AX; DI IS LENGTH OF COL
INC DI; ONE MORE LINE, DI IS THE WIDTH OF GRID IN TOTAL
MOV DX, [BP+4]; COLOR
MOV CX, [BP+10]; THE ROW NUMBER
INC CX; ONE MORE LINE
PUSH BX
ROWLOOP:
PUSH CX; SAVE CX FOR INNER LOOP
PUSH BX; SAVE OFFSET
MOV CX, DI; THE WIDTH OF EACH ROW LINE
HORLINELOOP:
MOV ES:[BX], DL
INC BX
LOOP HORLINELOOP
POP BX; RESTORE OFFSET
; CAL THE OFFSET OF NEXT ROW
MOV AX, [BP+6]; THE LENGTH OF EACH GRID
INC AX; THE DIFFERENCE OF LINE OF NEXT ROW
PUSH DX
MOV DX, 320
MUL DX
POP DX
ADD BX, AX; CHANGE LINE
POP CX; RESTORE THE ROW COUNTER
LOOP ROWLOOP
POP BX; THIS IS THE ORIGINAL OFFSET FOR COL USE
MOV CX, [BP+8]; THE COL NUMBER
INC CX; ONE MORE LINE
COLLOOP:
PUSH CX
PUSH BX
MOV CX, SI; THE HEIGHT OF TOTAL GRID
VERLINELOOP:
MOV ES:[BX], DL
ADD BX, 320
LOOP VERLINELOOP
POP BX
POP CX
; NEXT COL IS THE LENGTH OF GRID
MOV AX, [BP+6]; THE LENGTH OF GRID
INC AX; ONE MORE LINE
ADD BX, AX
LOOP COLLOOP;
POP DI
POP SI
POP DX
POP CX
POP BX
POP AX
POP BP
RET 12
INTERNALDRAWGRID ENDP
;INPUT ROW, COL, SIZE OF EACH CELL
;OUT PUT X, Y OFFSET BY STACK
CALCOFFSET PROC
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
MOV CX, [BP+4]; THE SIZE OF CELL
INC CX; THE DIFFERENCE BTW TWO CELL
MOV AX, [BP+8]; THE ROW
MUL CX; EACH ROW OFFSET
MOV BX, AX; SAVE IN BX THE Y OFFSET
MOV AX, [BP+6]; THE COL
MUL CX; THE X DIFFERENCE
MOV [BP+8], AX; SAVE THE X
MOV [BP+6], BX; SAVE THE Y
POP CX
POP BX
POP AX
POP BP
RET 2
CALCOFFSET ENDP
REFRESH PROC
PUSH AX
PUSH BX
PUSH CX
MOV AX, 00H
MOV CX, 64000
MOV BX, 0
LOCAL1:
MOV ES:[BX], AL
INC BX
LOOP LOCAL1
POP CX
POP BX
POP AX
RET
REFRESH ENDP
;INPUT: ORIGIN OF X,Y,ROW,COL,SIZE OF CELL,COLOR
FILLGRID PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV CX, [BP+6]; THE SIZE OF CELL
MOV AX, [BP+10]; ROW INDEX
PUSH AX; PREPARE PARAM FOR "CALCOFFSET" CALL
MOV AX, [BP+8]; THE COL INDEX
PUSH AX
PUSH CX; PASS THE SIZE
CALL CALCOFFSET
POP BX; IT IS Y OFFSET
ADD BX, [BP+12]; PLUS ORIGINAL Y
POP AX; THE NEW X
ADD AX, [BP+14]; PLUS ORIGINAL X
MOV DX, [BP+4]; THE COLOR
INC AX
INC BX
PUSH AX; X
PUSH BX; Y
PUSH CX; THE SIZE OF BOX
PUSH DX; THE COLOR OF BOX
CALL DRAWBOX
POP DX
POP CX
POP BX
POP AX
POP BP
RET 12
FILLGRID ENDP
; INPUT X,Y
DRAWGRID PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
MOV AX, [BP+6]; THE X
PUSH AX
MOV AX, [BP+4]; THE Y
PUSH AX
MOV AX, DIM
PUSH AX
PUSH AX
MOV AX, CELLSIZE
PUSH AX
MOV AX, 0EH; THE COLOR OF YELLOW
PUSH AX
CALL INTERNALDRAWGRID
POP AX
POP BP
RET 4;
DRAWGRID ENDP
;INPUT: X,Y,LENGTH,COLOR BY STACK
;OUTPUT: NONE
;FUNCTION: DRAW HORIZONTAL LINE WITH STARTING COORDINATE, LENGTH, COLOR,
DRAWHORLINE PROC
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH ES
MOV AX, 0A000H
MOV ES, AX
MOV AX, [BP+8]; THE Y
MOV BX, 320
MUL BX
ADD AX, [BP+10]; X
MOV BX, AX; BX HOLDS THE OFFSET ORIGIN
MOV CX, [BP+6]; THE LENGTH
MOV AX, [BP+4]
HLINE:
MOV ES:[BX], AL; DRAW THE LINE
INC BX
LOOP HLINE
POP ES
POP CX
POP BX
POP AX
POP BP
RET 8
DRAWHORLINE ENDP
DRAWVERLINE PROC
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH ES
MOV AX, [BP+8]; THE Y
MOV BX, 320
MUL BX
ADD AX, [BP+10]; ADD THE X
MOV BX, AX; BX HOLDS THE OFFSET
MOV CX, [BP+6]; THE LENGTH
MOV AX, [BP+4]; THE COLOR
VLINE:
MOV ES:[BX], AL
ADD BX, 320
LOOP VLINE
POP ES
POP CX
POP BX
POP AX
POP BP
RET 8
DRAWVERLINE ENDP
ENTERTEXT PROC
PUSH AX
MOV AH, 00H
MOV AL, 03H
INT 10H
MOV AX, 0B800H
MOV ES, AX
POP AX
RET
ENTERTEXT ENDP
;INPUT: NONE
;OUTPUT: NONE
;FUNCTION SIMPLY WAIT FOR ANY KEY TO BE PRESSED
WAITRETURN PROC
PUSH AX
XOR AX, AX
MOV AH, 01H
CHECK:
INT 21H
CMP AL, 0DH
JNE CHECK
POP AX
RET
WAITRETURN ENDP
;INPUT: X, Y, LENGTH, COLOR BY STACK
;OUTPUT: NONE
;FUNCTION: DRAW A BOX OF WHICH THE LEFTTOP HAS COORDINATE OF (X,Y),LENGTH, COLOR
;SAVE ES INTERNALLY,
DRAWBOX PROC NEAR
PUSH BP
MOV BP, SP
PUSH AX
PUSH BX
PUSH CX
PUSH DX
PUSH ES
MOV AX, 0A000H
MOV ES, AX
MOV BX, [BP+10]; X
MOV AX, [BP+8]; Y
MOV CX, 320
MUL CX
ADD BX, AX; BX IS OFFSET=320* Y + X
MOV AX, [BP+4]; COLOR
MOV CX, [BP+6]; R
MOV DX, CX ;DX SAVE LENGTH
BOXLOOP:
PUSH CX; SAVE OUTTER COUNTER
PUSH BX; SAVE OFFSET
MOV CX, DX; NEW START
SINGLELOOP:
MOV ES:[BX], AL
INC BX
LOOP SINGLELOOP
POP BX
ADD BX, 320;NEXT LINE
POP CX
LOOP BOXLOOP
POP ES
POP DX
POP CX
POP BX
POP AX
POP BP
RET 8
DRAWBOX ENDP
END