Ten Dots
Ten Dots

Reputation: 25

A program to find maximum and minimum number from an array

I wrote the following program which finds maximum and minimum number from an array of 10 numbers but it isn't giving me the correct minimum value,

[org 0x0100]

start:
    mov byte [swap],0
    mov bx,0
loop1:
    mov al,[data+bx]
    cmp  al,[data+bx+1]
    jbe noswap
hswap:
    mov dl,[data+bx+1]
    mov [data+bx+1],al
    mov [data+bx],dl
noswap:
    add bl,1
    cmp bx,9
    jnz loop1
heckswap:
    cmp byte [swap],0
    jnz start
store:
    mov al,[data]
    mov [min],al
    mov bl,[data+9]
    mov [max],bl

mov ax,0x4c00
int 0x21

data: db 2,10,3,4,7,8,6,5,9,1
swap: db 0
max: db 0
min: db 0

It should give the minimum value 1 but it is giving me the value of first memory address i.e, whatever is stored in [data] after swapping. The code is to be compiled using 8086 architecture.

Upvotes: 2

Views: 5245

Answers (1)

Fifoernik
Fifoernik

Reputation: 9899

Your code, which is in fact a BubbleSort, already uses nested loops.
The inner loop is loop1 and the outer loop is start.

The problem is that the outer loop never iterates because you fail to set its controlling variable swap! You need to make it TRUE whenever you perform a swap:

start:
    mov byte [swap], 0
    mov bx, 0
loop1:
    mov al, [data+bx]
    cmp al, [data+bx+1]
    jbe noswap
hswap:
    mov dl, [data+bx+1]
    mov [data+bx+1], al
    mov [data+bx], dl
    mov byte [swap], -1       ;ADD THIS 
noswap:
    add bl, 1
    cmp bx, 9
    jnz loop1
heckswap:
    cmp byte [swap], 0
    jne start

To make your BubbleSort more efficient, you need to reduce the number of elements to process on each iteration of the outer loop. Instead of comparing BX to a fixed value of 9 (because there are 10 elements in the array), you should compare it to a decreasing value in a register, say CX:

    mov cx, 9                 ; !!!
start:
    xor bx, bx                ;Just another optimization
    mov [swap], bl            ;Just another optimization
loop1:
    mov al, [data+bx]
    cmp al, [data+bx+1]
    jbe noswap
hswap:
    mov dl, [data+bx+1]
    mov [data+bx+1], al
    mov [data+bx], dl
    mov byte [swap], -1
noswap:
    inc bx                    ;Just another optimization
    cmp bx, cx                ; !!!
    jnz loop1
heckswap:
    dec cx                    ; !!!
    jz  store                 ; !!! Done
    cmp byte [swap], 0
    jne start
store:

Although finding the minimum and maximum is a nice by-product of sorting, you should follow the advice given in this comment. Getting the results will be so much faster!

Below is my implementation of it.

  1. I start by arbitrarily choosing the last element of the array as both the minimum (in AL) and the maximum (in DL).
  2. Then I iterate over the rest of the array and each time I find an element that is smaller than the current minimum in AL, I set that element as the new current minimum.
  3. Similarly each time I find an element that is bigger than the current maximum in DL, I set that element as the new current maximum.

You can traverse the array going from first to last element or from last to first element. I chose the latter because it saves me from writing an extra cmp instruction.

 mov al, [data+9]  ;Min
 mov dl, al        ;Max
 mov bx, 8
Repeat:
 mov cl, [data+bx]
 cmp cl, al
 jae NotSmaller
 mov al, cl
 ;;; jmp NotBigger     ;Better without this
NotSmaller:
 cmp cl, dl
 jbe NotBigger
 mov dl, cl
NotBigger:
 sub bx, 1
 jnb Repeat
 mov [min], al
 mov [max], dl

Should your array contain signed numbers then you'd have to exchange the jae and jbe instructions for jge and jle respectively!

Upvotes: 2

Related Questions