5
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ Welcome to Code Review! This looks a worthwhile challenge, but please edit to identify the processor (x86?) and OS (if any) on which this is intended to run. Thanks! \$\endgroup\$ – Toby Speight Jul 10 at 13:54
4
\$\begingroup\$

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.
\$\endgroup\$
  • 2
    \$\begingroup\$ Why did you promote a non-existing addressing mode ? The 8086 has limited possibilities for addressing memory. \$\endgroup\$ – Fifoernik Jul 18 at 15:24
3
\$\begingroup\$

Optimizations

Why are you so keen on zeroing the registers at the completion of the program? Drop those and you'll have made your first optimization already.

Don't use mov si, 0 to zero the register. Use xor si, si. It's shorter (codesize) and faster (execution speed).

Instead of using lea bx, array use mov bx, array (NASM style) or mov bx, offset array (MASM style). The mov variant has a shorter encoding.

Addressing the array will be simpler using a single index (or base) register.

 ORG  100h

 mov  cl, n
 mov  ch, -128     ;Array has numbers ranging from -128 to +127
 jcxz Done         ;In case the array is empty
 mov  si, array
More:
 cmp  [si], ch
 jle  NotBigger
 mov  ch, [si]     ;New MAX goes from -128 -> 4 -> 69
NotBigger:
 inc  si
 dec  cl
 jnz  More
Done:
 ret               ;Back to DOS

array DB 04h, 45h, 32h, 23h, 09h
n     DB 5

For a faster code, because that's what you get with less jumping around (but not necessarily less jump instructions!):

If the array has unsigned numbers use mov ch, 0 and also jbe More:

 ORG  100h

 mov  cl, n
 mov  ch, 0        ;Array has numbers ranging from 0 to 255
 mov  si, array-1
More:
 inc  si
 sub  cl, 1
 jb   Done         ;Happens first time if the array is empty
 cmp  [si], ch
 jbe  More         ;NotBigger
 mov  ch, [si]     ;New MAX goes from 0 -> 4 -> 69
 jmp  More
Done:
 ret               ;Back to DOS

array DB 04h, 45h, 32h, 23h, 09h
n     DB 5

The speed gain comes from the fact that a conditional jump that is taken requires many more cycles than a conditional jump that is not taken.


If the array has signed numbers use mov ch, -128 and also jle More:

 ORG  100h

 mov  cl, n
 mov  ch, -128     ;Array has numbers ranging from -128 to +127
 mov  si, array-1
More:
 inc  si
 sub  cl, 1
 jb   Done         ;Happens first time if the array is empty
 cmp  [si], ch
 jle  More         ;NotBigger
 mov  ch, [si]     ;New MAX goes from -128 -> 4 -> 69
 jmp  More
Done:
 ret               ;Back to DOS

array DB 04h, 45h, 32h, 23h, 09h
n     DB 5
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.