Home > database >  Min and max from numbers read assembly
Min and max from numbers read assembly

Time:02-08

I've just started learning assembly and I just trying things to see how it works

I have the code below that should read 5 numbers and display the min or max depending on the mnemonic used jg or jl

I try to implement it in order to read the 5 numbers and then store somewhere the min and max, but i don't understand really well why I can't create variables like a min,max and aux then store there the last value from ax register in aux and compare it to the new value from ax and so on

I think in this way because it's the aprroach that I would use in a C program

#include <stdio.h>
int main(){
    int min,max,aux;
    scanf("%d%d",&min,&max);
    
    if(min>max){
        aux=min;
        min=max;
        max=min;
    }

    for(int i=0;i<4;i  ){

    scanf("%d",&aux);

    if(max<aux) max=aux; 

    if(min>aux) min=aux;

    }
    printf("%d %d",max,min);
}

But I can't assign as I thought like mov max,ax

Another problem that I had is that I can`t make a function to call it to compare, it just give an unwanted output

The code read the 5 numbers then starts to compare them and save the max/min value in ax register then print it out I used the si register as an aux variable because i couldn't find another solution(the si register is completly random chosen)

.model small
.stack 100h
.data
msg1 db "Number 1:$"
msg2 db "Number 2:$"
msg3 db "Number 3:$"
msg4 db "Number 4:$"
msg5 db "Number 5:$"
max db "Max :$"
 num1 db ?
 num2 db ?
 num3 db ?
 num4 db ?
 num5 db ?
 ; num6 db ?
.code
mov bl, 00h
mov bh, 9fh
start:
  mov ax, @data
  mov ds, ax
  
  ;nr1
    mov dx, offset msg1
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num1,al
;nr2
    mov dx, offset msg2
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num2,al
;nr3    

    mov dx, offset msg3
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num3,al

  
  ;nr4    

    mov dx, offset msg4
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num4,al
    
    ;nr5    

    mov dx, offset msg5
    mov ah, 09h
    int 21h
    
    call readNr
    push dx
    mov num5,al
    

;max
    mov dx, offset max
    mov ah, 09h
    int 21h
  
; ;compar:
pop ax
pop dx
mov si,dx
cmp ax,si
  jg exit
  jmp maxim
  
max: 
mov ax,si
;jmp exit

exit: 
mov ax,ax
;loop compar


xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit1
  jmp maxim1
  
maxim1: 
mov ax,si
;jmp exit

exit1: 
mov ax,ax
;loop compar


xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit2
  jmp maxim2
  
maxim2: 
mov ax,si
;jmp exit

exit2: 
mov ax,ax

xor si,si
pop dx
mov si,dx
cmp ax,si
  jg exit3
  jmp maxim3
  
maxim3: 
mov ax,si
;jmp exit

exit3: 
mov ax,ax

call displayNr
jmp skipProceduri


readNr proc ;number will be created in dx
    xor bx, bx
    xor dx, dx
    xor cx, cx 
    mov cx, 10
    
    readCf:
        mov ah, 01h
        int 21h
        cmp al, 13
            je finish
        sub al, 48
        mov bl, al
        mov ax, dx
        mul cx
        add ax, bx
        mov dx, ax
        jmp readCf
    
    finish:    
    ret
endp


displayNr proc   
    mov bx, 10
    xor cx, cx
    
    descNr:
        xor dx, dx
        div bx
        inc cx
        push dx
        cmp ax, 0
            je displaynr
        jmp descNr
        
    displaynr:
        pop dx
        add dl, 48
        mov ah, 02h
        int 21h
    loop displaynr

    ret
endp

skipProceduri:

    mov ah, 4ch
    int 21h

end start

CodePudding user response:

Your assembly code seems correct! It does contain a lot of redundant instructions though.

Your solution that works from 5 numbers pushed on the stack deserves a loop:

  pop  ax        ; Consider 5th number as current max
  mov  cx, 4
TheLoop:
  pop  dx        ; 4th, 3rd, 2nd, and 1st number
  cmp  dx, ax
  jng  NotGreater
  mov  ax, dx    ; Set new max
NotGreater: 
  loop TheLoop
  call displayNr

Working from memory based variables

But I can't assign as I thought like mov max,ax

When you define your max variable like max db ?, the assembler will complain about mismatching sizes. Just define all your variables as words:

max dw ?
min dw ?
aux dw ?

Pay attention to how you define your labels! The code already has a max label to denote some message (max db "Max :$"). See in below snippet how I solved this.

It's possible to obtain both the maximum and the minimum from a single loop.
Next code also demonstrates the use of memory based variables although working from registers would be more efficient (as would refraining from using the slow LOOP instruction)!

       mov  cx, 5
TheLoop:
       pop  ax        ; 5th, 4th, 3rd, 2nd, and 1st number
       cmp  ax, max
       jng  NotGreater
       mov  max, ax    ; Set new maximum
NotGreater:
       cmp  ax, min
       jnl  NotLess
       mov  min, ax    ; Set new minimum
NotLess:
       loop TheLoop

       mov  dx, offset msgMax
       mov  ah, 09h
       int  21h
       max  ax, max
       call displayNr

       mov  dx, offset msgMin
       mov  ah, 09h
       int  21h
       max  ax, min
       call displayNr

  ...

max    dw -32768       ; Smallest word integer
min    dw 32767        ; Biggest word integer
msgMax db "Max = $"
msgMin db 13, 10, "Min = $"
  •  Tags:  
  • Related