COMMENT*
Here's an .EXE program that prints out an array of 16-bit numbers (that
I just made up), then bubble-sorts them, following Tom's algorithm, and
then skips a line, and prints the sorted array. The bubble-sort
procedure that I wrote works properly only with UNSIGNED numbers. If
you want to sort signed numbers, you'll have to change the conditional
jump statement, at the least. The number-printing procedure only works
with unsigned numbers, too...
for (i1=0; i1<limit; i1++)
{
for (i2=i1; i2<limit; i2++)
{
if (elem[i1]>elem[i2])
{
tmp = elem[1];
elem[1] = elem[2];
elem[2] = tmp;
}
}
}
Written by Julian H. Schmidt - public domain code.
assembles with MASM.
For an array of nubmers, like this: array[limit],
This will sort the numbers from least to greatest.
END OF COMMENT*
;Equates:
ELEMENTS = 11
_data segment para 'DATA'
array dw 1000,4000,245,15567,23,60789,4321,123,321,6,6543
Store db 5 dup(0) ;Storage for ASCII to print.
CRLF db 0ah,0dh ;Carriage Return and Linefeed.
_data ends
_code segment para 'CODE'
assume cs:_code,ds:_data,ss:_stack
COMMENT*
BUBBLE - performs a bubble sort on an array of 16-bit integers.
Entry:
DS:BX - Pointer to 1st (word) element of the array.
AX - Size of the array (in words).
Exit:
Nothing
Changes:
Flags, and just about every register but IP, SP, etc. IF IN DOUBT,
SAVE THE REGISTER BEFORE CALLING THIS PROCEDURE.
END OF COMMENT*
Bubble proc ;This is the sorting procedure.
mov cx,ax ;Size of array in CX for loop control.
xor si,si ;Put a zero in our index register.
OuterLoop:
mov bp,cx ;BP is our inner-loop iteration counter.
mov di,si
InnerLoop:
mov ax,[si+bx] ;Move array element into AX.
mov dx,[di+bx] ;Move another element into DX.
cmp ax,dx ;Is AX 'above' (unsigned) DX?
ja SwitchElements ;If so, jump and switch the elements.
jmp short InnerEnd ;If not, skip the switch.
SwitchElements:
mov [di+bx],ax ;Switch two array elements.
mov [si+bx],dx ; ...they are already in AX and BX!
InnerEnd:
add di,2 ;Point to next array element.
dec bp
cmp bp,0 ;Is iteration count zero?
jnz InnerLoop ;If not, continue looping...
add si,2 ;Point to next array element.
loop OuterLoop ;Loop again (until CX == 0).
ret ;This procedure is finit!
bubble endp
;----------------------------------------------------
; Procedure DisplayDecimal |
; Entry: BX= number to display in decimal |
; Exit : Registers corrupt |
; This will not check the thousandths place... |
; This procedure courtesy of someone in 80XXX? |
;----------------------------------------------------
DisplayDecimal proc ;Beginning of procedure DisplayDecimal.
mov ax,10000 ;First check ten-thousandths place.
xor cx,cx
dd_loop1:
xor dx,dx ;Clear DX so that DX:AX = AX.
mov cl,0FFh ;Start counter at -1 (signed).
dd_loop2:
inc cl ;At least one increment to zero.
sub bx,ax ;Subtract the place representor
; from the test value.
jnc dd_loop2 ;If the result isn't negative keep going.
add bx,ax ;Add to make the test value
; non-negative (restore).
;This brings it back to the original value.
dd_noadd: ;Digit is now in CL...
add cl,30h ;Add ASCII '0'.
;Now, CL holds Ascii value of the number.
push cx ;Put the digit on the stack.
;Number will be on stack in the reverse order.
mov cx,10
idiv cx ;divide DX:AX by 10, result in AX,
; remainder in DX
or ax,ax ;Test if AX is zero (1 div 10 = 0 remainder 1)
jnz dd_loop1 ;If not do the next place.
;Now, I must pop the 5 digits and store them...
mov cx,5
StoreLoop:
pop ax ;Get a digit from the stack
mov bx,offset Store
add bx,cx
dec bx
mov byte ptr[bx],al ;Store the digit.
loop StoreLoop
RET ; else return
DisplayDecimal endp ;End of procedure DisplayDecimal.
;----------------------------------------------------------------------
bub proc ;This is the program entry point.
mov ax,_data ;Make our data segment accessible.
mov ds,ax
mov cx,ELEMENTS ;CX is for loop control.
xor si,si ;SI used for indexed addressing.
PrintLoop1: ;Print out the initial (unsorted) array:
mov bx,[array+si] ;Get the element into BX.
push cx ;Save our loop control register.
call DisplayDecimal ;Translate to ASCII.
mov ah,40h ;Request function 40h (DOS).
mov bx,0001 ;Standard Output Handle in BX.
mov cx,7 ;Print out 5 characters (+CRLF).
mov dx,offset Store ;DX is pointer to data.
int 21h ;Dos's Output to Device (Handle).
pop cx ;Restore loop-control register.
add si,2 ;Point SI to next word in array.
loop PrintLoop1 ;Loop while elements exist to print.
mov ax,ELEMENTS ;AX gets length of the array.
lea bx,array ;Point BX to the array beginning.
call bubble ;Sort the sucker.
mov ah,40h ;Request function 40h (DOS).
mov bx,0001 ;Standard Output.
mov cx,2 ;Number of bytes to print out.
mov dx,offset CRLF ;Point DX to data to print.
int 21h ;Dos's Output to Device (STDOUT)
mov cx,ELEMENTS ;CX is for loop control.
xor si,si ;SI used for indexed addressing.
PrintLoop2:
mov bx,[array+si] ;Get the element into BX.
push cx ;Save our loop-control register.
call DisplayDecimal ;Translate to ASCII.
mov ah,40h ;Request function 40h (DOS).
mov bx,0001 ;Standard Output Handle in BX.
mov cx,7 ;Print out 5 characters (+CRLF).
mov dx,offset Store ;DX is pointer to data.
int 21h ;Dos's Output to Device (Handle).
pop cx ;Restore loop-control register.
add si,2 ;Go to next word in array.
loop PrintLoop2 ;Print out all of the sorted elements.
mov ax,4c00h ;Request function 4Ch (DOS).
int 21h ;Dos's Terminate program function.
bub endp
_code ends
_stack segment 'STACK'
db 100 dup('STACK')
_stack ends
End bub