Why is my code not showing the largest number?

Viewed 89
include 'emu8086.inc'
org 100h

.model small
.data
     arr db 8,5,3,6,2
.code 
main proc

        mov ax,@data
        mov ds,ax

        mov si,offset arr
        mov cx,5
        mov bl,[si]

        loopA:
        cmp [si],bl ; 2,3
          
        
        
        jge large 
        jle small
        compare:  
        
        inc si
        loop loopA 
        
        

        print "Largest value in array is :" 
        print "Smallest value in array is :"
        add bl,48
        mov dl,bl
        mov ah,2
        int 21h

        large: 
        
        mov bl,[si]
        jmp compare   
        
        small:
        mov bl,[si]
        jmp compare 

main endp

Output:

The largest value in array is: The smallest value in array is: 2

enter image description here

1 Answers
  jge large 
  jle small
large: 
  mov bl,[si]
  jmp compare  
small:
  mov bl,[si]
  jmp compare

Whether you find an element to be larger or smaller, you always consider it to be the next reference. This will always lead to displaying the last array element.

In your loop you should only set a new BL on the one condition and skip modifying BL on the other condition:

loopA:
 cmp  [si], bl
 jng  NotLarger    ; Skip on condition "Not larger"
 mov  bl, [si]     ; Set on condition "Larger"
NotLarger:
 inc  si
 loop loopA
print "Largest value in array is :" 
print "Smallest value in array is :"

It's confusing to see both messages displayed together!
First concentrate on the "Largest" task with the code I showed above, then add a separate but very similar code for the "Smallest". You would use jnl (JumpOnNotLess).


Combining the codes for max and min

Still learning the basics of assembly programming, you would better keep away from the DOS .EXE format and start using the much simpler DOS .COM program format. All you need is having the directive ORG 100h at the top of your program. You won't have to set up any segment registers yourself, but you do need to put your variables (data) below the code. The execution will simply start at the top.

Since you want to display the messages on separate lines, you need to move the cursor to the start of the next row with the linefeed (10) and carriage return (13) codes.

All programs need to exit at some point. You need to write special code to do this. See in below program where to write this.

include 'emu8086.inc'
org 100h

  mov  si, offset arr
  mov  cx, 5
  mov  bl, [si]
MaxLoop:
  cmp  [si], bl
  jng  NotLarger    ; Skip on condition "Not larger"
  mov  bl, [si]     ; Set on condition "Larger"
NotLarger:
  inc  si
  loop MaxLoop
  PRINT "Largest value in array is : "
  add  bl, 48
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  PUTC 10           ; Linefeed
  PUTC 13           ; Carriage return

  mov  si, offset arr
  mov  cx, 5
  mov  bl, [si]
MinLoop:
  cmp  [si], bl
  jnl  NotSmaller   ; Skip on condition "Not smaller"
  mov  bl, [si]     ; Set on condition "Smaller"
NotSmaller:
  inc  si
  loop MinLoop
  PRINT "Smallest value in array is : "
  add  bl, 48
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  mov  ax, 4C00h    ; DOS.TerminateProgram
  int  21h

; ------------------
arr db 8, 5, 3, 6, 2

Combining the codes for max and min in a single loop

I have included this variant because in programming it's often efficient to do more than one thing in a loop. This will minimize the impact that the loop overhead has on the execution time (in general).

include 'emu8086.inc'
org 100h

  mov  si, offset arr
  mov  cx, 5
  mov  bh, [si]
  mov  bl, bh
MaxMinLoop:
  cmp  [si], bh
  jng  NotLarger    ; Skip on condition "Not larger"
  mov  bh, [si]     ; Set on condition "Larger"
NotLarger:
  cmp  [si], bl
  jnl  NotSmaller   ; Skip on condition "Not smaller"
  mov  bl, [si]     ; Set on condition "Smaller"
NotSmaller:
  inc  si
  loop MaxMinLoop
  add  bx, 3030h

  PRINT "Largest value in array is : "
  mov  dl, bh
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  PUTC 10           ; Linefeed
  PUTC 13           ; Carriage return

  PRINT "Smallest value in array is : "
  mov  dl, bl
  mov  ah, 02h      ; DOS.PrintCharacter
  int  21h

  mov  ax, 4C00h    ; DOS.TerminateProgram
  int  21h

; ------------------
arr db 8, 5, 3, 6, 2
Related