Search code examples
assemblynasmx86-16bubble-sortdosbox

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.


Solution

  • 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!