How to do a sorting algorithm

78 views Asked by At

My teacher gave us an assignment to write source code that sorts numbers. The code is supposed to be made out of 2 procedures.
Procedure 1 (Minimum) receives the address of the first element in a list that needs to be sorted in pass by reference. It also receives, in pass by value, the number of elements and should return the position of the smallest element.
Procdure 2 is called "swap". It receives the position of the head of the list and the position of the smallest element in pass by reference, swapping their values.

These two procedures should be placed one after the other, and one should not be called within the other.

At the end of the code, the list should be sorted from the smallest to the largest.
I need help doing the Swap procdure. If someone can help me understand the steps of how to do the procdure I'd really appreciate it. For now my code is:

IDEAL
MODEL small
STACK 100h
DATASEG
; --------------------------
; Your variables here
; --------------------------

arr    dw 4, 6, 2
amount dw 0

CODESEG

proc min   ;saves the offset of the smallest values in the DATASEG
    push bp
    mov bp, sp
    mov di, [bp+4]   ;di is now pointing to the first variables in the array
    mov ax, 0ffffh
    mov cx, [amount]  ;the loop will run the number of variables
lop:
    cmp ax, [di]    ;if the value in di is smaller than ax, it'll replace what's in ax
    jb lop1
    mov ax, [di]
    mov [bp+4], di  ;saves the offset of the smallest value in the array
lop1:
    add di, 2   ;incrementing the offset of the array
    loop lop
    
   pop bp
  ret   
endp min

proc swap
   push bp
   mov bp, sp
   
   pop bp
  ret
endp swap

start:
    mov ax, @data
    mov ds, ax
; --------------------------
; Your code here
; --------------------------
    xor ax, ax
    mov bx, offset arr   ;sets bx to point to the start of the array
check:
    cmp [word ptr bx], 0   ;if the value in bx is 0, it means the array is over
    jz exit_check
    add bx, 2
    inc ax
    jmp check
exit_check:
    mov [amount], ax    ;save the amount of variables in the array

    mov bx, offset arr
    push bx     ;save the offset of the array (pass by reference)
    
    call min
    call swap
    
exit:
    mov ax, 4c00h
    int 21h
END start
1

There are 1 answers

0
Sep Roland On

Procedure 1 (Minimum) receives the address of the first element in a list that needs to be sorted in pass by reference. It also receives, in pass by value, the number of elements and should return the position of the smallest element.

  • For the 'pass by reference' you are using a parameter on the stack, yet for the 'pass by value' you just use some global variable. I would prefer you not use this weird mixed calling convention and put the number of elements on the stack too.
  • The min proc that currently expects 1 stacked argument leaves this argument behind on the stack. Either have the caller remove it with add sp, 2, or else have the callee remove it with ret 2.
  • For now you are returning the result on the stack where the (only) parameter was. A cleaner way would be to return the address in the AX register and leave the stacked argument intact. In doing so, you could re-use the argument for your second proc that also is expecting that same address.

In next solution I re-use both argument slots.

proc min
  push bp
  mov  bp, sp
  push bx

  mov  cx, [bp + 6]   ; Number of elements to check
  mov  bx, [bp + 4]   ; Address of the array
  mov  ax, 0FFFFh
lop:
  cmp  ax, [bx]
  jb   lop1
  mov  ax, [bx]
  mov  [bp + 6], bx   ; Address of the smallest element
lop1:
  add  bx, 2
  loop lop

  pop  bx
  pop  bp
  ret   
endp min

The caller uses:

  push word ptr [amount]
  push offset arr
  call min

  ;;; push ...        ; Contains result from 'min'
  ;;; push offset arr ; Is still present
  call swap
  add  sp, 4          ; Finally discard both arguments

The missing 'swap' procedure

proc swap
  push bp
  mov  bp, sp
  push bx

  mov  bx, [bp + 6]   ; Address of smallest element
  mov  bp, [bp + 4]   ; Address of the array
  mov  ax, [bx]       ; -> AX is smallest element
  mov  dx, [ds:bp]    ; -> DX is first element
  mov  [bx], dx       ; Former first element is in vacated position
  mov  [ds:bp], ax    ; Smallest element is in front

  pop  bx
  pop  bp
  ret   
endp swap

At the end of the code, the list should be sorted from the smallest to the largest.

You will need to repeat the above.

By now, the test data 4,6,2 will have been modified to read 2,6,4.
A further run through the code will have to consider the second element (which is 6) to be the start of a new array having 2 elements (so 1 less than before). That particular run will then produce 4,6. Together with the 2 that was already in place, you end with the sorted array 2,4,6.