Find the maximum number in an array of numbers The task is to find the maximum number in an array of numbers.
I have taken every number in the array to be byte-sized.
I have written the code such that the result is stored in ch at the end.

The code is written to run on Intel 8086.

Code optimization and improvement required.

   org 100h

    ;registers: bx - to store the base address of the array of numbers
    ;si : to store the index of the current number in the array
    ;dl: to store the iterator value of the for loop in the program
    ;dh: to store the value of n(size of the array)
    ;ch: to store the maximum element
    ;ah: temporary register to store the current element, and to compare with 
    ;the number in ch


   lea bx,array
   mov si,0h
   mov dl,0h
   mov dh,n


   cmp dl,dh
   jge end


   mov cx,0h 
   ;to move the first value into the min-register to compare with other elements
   mov ch,[bx+si]
   inc dl
   inc si

loop:
   cmp dl,dh
   jge end    

   mov ah,[bx+si]
   inc si
   inc dl
   cmp ah,ch
   jle loop
   mov ch,ah
   jmp loop

end:

   mov ax,0h
   mov dx,0h
   mov bx,0h
   mov si,0h

   ret

array DB 4h,45h,32h,23h,9h
n DB 5
Undefined Behaviour

If you execute this code with n DB 0, it returns without setting ch to any value, leaving the result as undefined.

Signed Length

mov dl,0h
mov dh,n

cmp dl,dh
jge end


If n happens to be between 128 and 255, the jge will treat the comparison as if it was a signed comparison, and since 0 is not greater than or equal to any value between -128 and -1, inclusive, immediately jump to the end, again leaving ch as an undefined value.

You should use jae instead, so you can have up to 255 values in array.

Signed comparison

Does your array of values represent unsigned bytes, or signed bytes?  If your array contains 0FFh, is that the largest possible value, or one smaller than zero?

If the data is supposed to be signed, you're good.  If it was supposed to be unsigned bytes, you again should change the jle to jbe.

Unnecessary Register Usage

You execute mov cx,0h, but nowhere do you use cl, so are unnecessarily destroying cl.

You execute mov ah,[bx+si] and use mov ax,0h to clean-up at the end.  Again, nowhere have you used al, so you've unnecessarily destroyed al.

If you used cl instead of ah, you wouldn't need to destroy ax at all.

Use of si appears unnecessary.  Instead of based-index addressing mode:

mov cl,[bx+si]
inc si


you could use register indirect addressing mode:

mov cl,[bx]
inc bx


Better Registers

cx is the standard for loop counts.  ax is the standard for function return values.  si is the standard for source indexing.  So ...

Have your function store and return the maximum in al.  Use ah to fetch values from the array, and zero it at the end.  As a bonus, ax could also be considered the return value.  (If the array is intended to hold signed data, then use cbw to sign extend al into ax instead of zeroing ah.)

If you used cx for your array length, and decrement to zero, you could use one LOOP instruction instead of a pair of instructions to perform the compare-and-branch.  As another bonus, it will already be zero by the end, so you won't need to clear it.

Store the array address in si, and use cx for double duty by using based-index addressing (mov ah, [cx+si]) to index into your array.  Of course, you'll be searching backwards, which still fine for finding the maximum.  You'd just have to be careful to include the 0th value, and exclude the nth value (dec cx before the fetch, not afterwards).

Final tally:


return value in ax
cx zeroed (automatically)
si cleared (manually)
All other registers unchanged.