Home > Blockchain >  Sorting an array in assembly 8086 16 bit
Sorting an array in assembly 8086 16 bit

Time:11-25

I am trying to sort an array by using functions that finds the smallest number in an array, and the other swaps two variables. But for some reason the array doesn't change and stays the same. I thing I have a problem with the stack but I can't find it.

This is my code: sorry its long and not organized. I just started assembly. `

org 100h
    
     jmp start
        array db 1,9,3,6,3 **;should get 1,2,3,6,9**
        min_in_array dw ?
        
    start: 
       
       lea si, array         
       push 5 
       push si
       call sortArray 
       pop bx
       pop bx
       mov ah, 0
       int 16h
       ret
        

;doesn't work
PROC sortArray
    push bp
    mov bp, sp
    
    mov dx, 0 ;the index
    mov cx, [bp 6];size
    mov di, [bp 4];array  
    
    loop_arr: 
        add di, dx
        push di
        call findMin
        pop di
        
        
        sub di, dx
         
        add di, min_in_array 
        push dx        
        push di
        call swap
        pop di
        pop dx
        sub di, min_in_array
        inc dx
        
        mov ax, [di]
        loop loop_arr
        
   
     mov sp, bp
     pop bp
   
     ret
ENDP sortArray    


;works
PROC findMin
    push bp
    mov bp, sp
    sub sp, 4
    
    mov cx, 0 ;init the counter
    mov di, [bp 4]
    mov al, [bp-2] ;initialising the min save var
    mov al, [di] 
    
    mov bx, [bp-4] ;the index to save
    mov bx, 0
    
    run:
        cmp al, [di] 
        ja change_min 
        cmp cx, 4 ;check if cx is lower than the size of the array
        inc cx ; 1
        inc di ;move forward in the array
        jb run ;check again
        jmp fin ;finished - cx = size
        
    change_min:        
        mov al, [di] ;change the min
        mov bx, cx  ;assign the index
        inc di 
        cmp cx, 4  
        je fin
        inc cx
        jmp run
    
         
    fin: 
        mov sp, bp
        pop bp
        mov cx, 0
        
        mov min_in_array, bx
        ret 
ENDP findMin                               


;function works
PROC swap       
    ;creates fram  
    push    bp
    mov     bp,sp  
    
    sub sp,2 ;make space for local temp 
    mov bx, [bp 6]
    mov cx, [bp 4]
    ;swaping using the temp varaiable
    mov [bp-2], bx
    mov bx, cx
    mov cx, [bp-2]
         
    ;close frame
    mov sp, bp
    pop bp
    ret
ENDP swap  

`

CodePudding user response:

I have a problem with the stack but I can't find it.

Your use of the stack is actually fine: prologue, epilogue, cleaning.
But there's one additional thing that the stack is good at, and that's preserving register values. Your sortArray procedure depends on the CX register, but you destroy its value in the findMin and swap procedures!

You say findMin works, but I assure you it doesn't. Other than not preserving CX and containing a lot of unused code, findMin always processes 5 elements eventhough the supplied address moved up with each invokation, meaning you are processing garbage that follows the original array in memory. Moreover the result that you store in the min_in_array variable is an offset in the unsorted partition of the array, but after returning, sortArray will use this same value as an offset in the original array. Can't work that way...

You say swap works, but I assure you it doesn't. What you supply to this procedure is an offset in the original array and an (wrongly calculated) address within the original array. You fetch these arguments from the stack and only swap these in registers, nothing more. You never read/write in the array, so there's no swapping taking place.

See if next code points you in the right direction:

    add  di, dx
    push cx         ; Number of elements in the unsorted partition
    push di         ; Address of the start of the unsorted partition
    call findMin    ; -> AX (BL CX SI)
    pop  di
    pop  cx

    push ax         ; Address of the Min from the unsorted partition
    push di         ; Address of the start of the unsorted partition
    call swap
    ...

; IN () OUT (ax) MOD (bl,cx,si)
PROC findMin
    push bp
    mov  bp, sp
    mov  cx, [bp   6]
    mov  si, [bp   4]
  min:
    mov  bl, [si] 
    mov  ax, si
  run:
    dec  cx
    jz   done
    inc  si
    cmp  bl, [si] 
    jb   run
    jmp  min                 ; Go change min
  done:
    pop  bp
    ret 
ENDP findMin
  • Related