.MODEL SMALL
.STACK 100H
.DATA
ARRAY DB 100 DUP(?)
.CODE
MAIN PROC
MOV AX, @DATA ; initialize DS
MOV DS, AX
LEA SI, ARRAY ; set SI=offset address of variable ARRAY
XOR BX, BX ; clear BX
@INPUT: ; loop label
MOV AH, 2 ; set output function
MOV DL, "?" ; set DL="?"
INT 21H ; print a character
MOV AH, 1 ; set input function
INT 21H ; read a character
CMP AL, 1BH ; compare AL with <ESC>
JE @END_INPUT ; jump to label @END_INPUT if AL=<ESC>
MOV CX, BX ; set CX=BX
JCXZ @NOT_PRESENT ; jump to label @NOT_PRESENT if CX=0
PUSH SI ; push SI onto the STACK
LEA SI, ARRAY ; set SI=offset address of variable ARRAY
@COMPARE: ; loop label
MOV DL, [SI] ; set DL=[SI]
CMP AL, DL ; compare AL with DL
JE @ALREADY_PRESENT ; jump to label @ALREADY_PRESENT if AL=DL
INC SI ; set SI=SI+1
LOOP @COMPARE ; jump to label @COMPARE while CX!=0
JMP @NOT_PRESENT ; jump to label @NOT_PRESENT
@ALREADY_PRESENT: ; jump label
POP SI ; pop a value from STACK into SI
JMP @SKIP_INPUT ; jump to label @SKIP_INPUT
@NOT_PRESENT: ; jump label
INC BX ; set BX=BX+1
MOV [SI], AL ; set [SI]=AL
INC SI ; set SI=SI+1
@SKIP_INPUT: ; jump label
MOV AH, 2 ; set output function
MOV DL, 0DH ; carriage return
INT 21H
MOV DL, 0AH ; line feed
INT 21H
PUSH SI ; push SI onto the STACK
LEA SI, ARRAY ; set SI=offset address of varibale ARRAY
CALL BUBBLE_SORT ; call the procedure BUBBLE_SORT
LEA SI, ARRAY ; set SI=offset address of varibale ARRAY
CALL PRINT_ARRAY ; call the procedure PRINT_ARRAY
POP SI ; pop a value from STACK into SI
MOV AH, 2 ; set output function
MOV DL, 0DH ; carriage return
INT 21H
MOV DL, 0AH ; line feed
INT 21H
JMP @INPUT ; jump to label @INPUT
@END_INPUT: ; jump label
MOV AH, 4CH ; return control to DOS
INT 21H
MAIN ENDP
;**************************************************************************;
;**************************************************************************;
;------------------------- Procedure Definitions ------------------------;
;**************************************************************************;
;**************************************************************************;
;**************************************************************************;
;----------------------------- PRINT_ARRAY ------------------------------;
;**************************************************************************;
PRINT_ARRAY PROC
; this procedure will print the elements of a given array
; input : SI=offset address of the array
; : BX=size of the array
; output : none
PUSH AX ; push AX onto the STACK
PUSH CX ; push CX onto the STACK
PUSH DX ; push DX onto the STACK
MOV CX, BX ; set CX=BX
MOV AH, 2 ; set output function
@PRINT_ARRAY: ; loop label
MOV DL, [SI] ; set DL=[SI]
INT 21H ; print a character
INC SI ; set SI=SI+1
LOOP @PRINT_ARRAY ; jump to label @PRINT_ARRAY while CX!=0
POP DX ; pop a value from STACK into DX
POP CX ; pop a value from STACK into CX
POP AX ; pop a value from STACK into AX
RET ; return control to the calling procedure
PRINT_ARRAY ENDP
;**************************************************************************;
;---------------------------- BUBBLE_SORT -------------------------------;
;**************************************************************************;
BUBBLE_SORT PROC
; this procedure will sort the array in ascending order
; input : SI=offset address of the array
; : BX=array size
; output : none
PUSH AX ; push AX onto the STACK
PUSH BX ; push BX onto the STACK
PUSH CX ; push CX onto the STACK
PUSH DX ; push DX onto the STACK
PUSH DI ; push DI onto the STACK
MOV AX, SI ; set AX=SI
MOV CX, BX ; set CX=BX
CMP CX, 1 ; compare CX with 1
JLE @SKIP_SORTING ; jump to label @SKIP_SORTING if CX<=1
DEC CX ; set CX=CX-1
@OUTER_LOOP: ; loop label
MOV BX, CX ; set BX=CX
MOV SI, AX ; set SI=AX
MOV DI, AX ; set DI=AX
INC DI ; set DI=DI+1
@INNER_LOOP: ; loop label
MOV DL, [SI] ; set DL=[SI]
CMP DL, [DI] ; compare DL with [DI]
JNG @SKIP_EXCHANGE ; jump to label @SKIP_EXCHANGE if DL<[DI]
XCHG DL, [DI] ; set DL=[DI], [DI]=DL
MOV [SI], DL ; set [SI]=DL
@SKIP_EXCHANGE: ; jump label
INC SI ; set SI=SI+1
INC DI ; set DI=DI+1
DEC BX ; set BX=BX-1
JNZ @INNER_LOOP ; jump to label @INNER_LOOP if BX!=0
LOOP @OUTER_LOOP ; jump to label @OUTER_LOOP while cX!=0
@SKIP_SORTING: ; jump label
POP DI ; pop a value from STACK into DI
POP DX ; pop a value from STACK into DX
POP CX ; pop a value from STACK into CX
POP BX ; pop a value from STACK into BX
POP AX ; pop a value from STACK into AX
RET ; return control to the calling procedure
BUBBLE_SORT ENDP
;**************************************************************************;
;--------------------------------------------------------------------------;
;**************************************************************************;
END MAIN
;**************************************************************************;
;**************************************************************************;
;------------------------------ THE END ---------------------------------;
;**************************************************************************;
;**************************************************************************;